diff --git a/api-guide/authentication/index.html b/api-guide/authentication/index.html index dfc424059..9b38ca47d 100644 --- a/api-guide/authentication/index.html +++ b/api-guide/authentication/index.html @@ -654,7 +654,7 @@ TokenAdmin.raw_id_fields = ('user',)
  • request.auth will be None.
  • Unauthenticated responses that are denied permission will result in an HTTP 403 Forbidden response.

    -

    If you're using an AJAX style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such as PUT, PATCH, POST or DELETE requests. See the Django CSRF documentation for more details.

    +

    If you're using an AJAX style API with SessionAuthentication, you'll need to make sure you include a valid CSRF token for any "unsafe" HTTP method calls, such as PUT, PATCH, POST or DELETE requests. See the Django CSRF documentation for more details.

    Warning: Always use Django's standard login view when creating login pages. This will ensure your login views are properly protected.

    CSRF validation in REST framework works slightly differently to standard Django due to the need to support both session and non-session based authentication to the same views. This means that only authenticated requests require CSRF tokens, and anonymous requests may be sent without CSRF tokens. This behaviour is not suitable for login views, which should always have CSRF validation applied.

    Custom authentication

    diff --git a/api-guide/exceptions/index.html b/api-guide/exceptions/index.html index 49cf6ee22..bccdbc6b2 100644 --- a/api-guide/exceptions/index.html +++ b/api-guide/exceptions/index.html @@ -485,7 +485,7 @@ Content-Length: 94

    Custom exception handling

    You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.

    -

    The function must take a pair of arguments, this first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.

    +

    The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.

    For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:

    HTTP/1.1 405 Method Not Allowed
     Content-Type: application/json
    diff --git a/api-guide/fields/index.html b/api-guide/fields/index.html
    index 70521bfbb..6c62e5b68 100644
    --- a/api-guide/fields/index.html
    +++ b/api-guide/fields/index.html
    @@ -598,7 +598,7 @@
                   

    Serializer fields

    Each field in a Form class is responsible not only for validating data, but also for "cleaning" it — normalizing it to a consistent format.

    -

    Django documentation

    +

    Django documentation

    Serializer fields handle converting between primitive values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.


    @@ -760,7 +760,7 @@ color_channel = serializers.ChoiceField(

    Corresponds to django.db.models.fields.DecimalField.

    Signature: DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)

    DateTimeField format strings.

    -

    Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style datetimes should be used. (eg '2013-01-29T12:34:56.000000Z')

    +

    Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style datetimes should be used. (eg '2013-01-29T12:34:56.000000Z')

    When a value of None is used for the format datetime objects will be returned by to_representation and the final output representation will determined by the renderer class.

    In the case of JSON this means the default datetime representation uses the ECMA 262 date time string specification. This is a subset of ISO 8601 which uses millisecond precision, and includes the 'Z' suffix for the UTC timezone, for example: 2013-01-29T12:34:56.123Z.

    auto_now_add model fields.auto_now and

    @@ -808,7 +808,7 @@ color_channel = serializers.ChoiceField(
  • input_formats - A list of strings representing the input formats which may be used to parse the date. If not specified, the DATE_INPUT_FORMATS setting will be used, which defaults to ['iso-8601'].
  • DateField format strings

    -

    Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style dates should be used. (eg '2013-01-29')

    +

    Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style dates should be used. (eg '2013-01-29')

    TimeField

    A time representation.

    Corresponds to django.db.models.fields.TimeField

    @@ -818,7 +818,7 @@ color_channel = serializers.ChoiceField(
  • input_formats - A list of strings representing the input formats which may be used to parse the date. If not specified, the TIME_INPUT_FORMATS setting will be used, which defaults to ['iso-8601'].
  • TimeField format strings

    -

    Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style times should be used. (eg '12:34:56.000000')

    +

    Format strings may either be Python strftime formats which explicitly specify the format, or the special string 'iso-8601', which indicates that ISO 8601 style times should be used. (eg '12:34:56.000000')

    DurationField

    A Duration representation. Corresponds to django.db.models.fields.DurationField

    @@ -853,7 +853,7 @@ The representation is a string following this format '[DD] [HH:[MM:]]ss[.u

    File upload fields

    Parsers and file uploads.

    The FileField and ImageField classes are only suitable for use with MultiPartParser or FileUploadParser. Most parsers, such as e.g. JSON don't support file uploads. -Django's regular FILE_UPLOAD_HANDLERS are used for handling uploaded files.

    +Django's regular FILE_UPLOAD_HANDLERS are used for handling uploaded files.

    FileField

    A file representation. Performs Django's standard FileField validation.

    Corresponds to django.forms.fields.FileField.

    diff --git a/api-guide/filtering/index.html b/api-guide/filtering/index.html index d7af9ceaf..887118583 100644 --- a/api-guide/filtering/index.html +++ b/api-guide/filtering/index.html @@ -486,7 +486,7 @@

    Filtering

    The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects.

    -

    Django documentation

    +

    Django documentation

    The default behavior of REST framework's generic list views is to return the entire queryset for a model manager. Often you will want your API to restrict the items that are returned by the queryset.

    The simplest way to filter the queryset of any view that subclasses GenericAPIView is to override the .get_queryset() method.

    @@ -557,7 +557,7 @@ class PurchaseList(generics.ListAPIView):

    You can also set the filter backends on a per-view, or per-viewset basis, using the GenericAPIView class-based views.

    -
    import django_filters
    +
    import django_filters.rest_framework
     from django.contrib.auth.models import User
     from myapp.serializers import UserSerializer
     from rest_framework import generics
    @@ -688,7 +688,7 @@ class ProductFilter(django_filters.rest_framework.FilterSet):
     
     

    SearchFilter

    -

    The SearchFilter class supports simple single query parameter based searching, and is based on the Django admin's search functionality.

    +

    The SearchFilter class supports simple single query parameter based searching, and is based on the Django admin's search functionality.

    When in use, the browsable API will include a SearchFilter control:

    Search Filter

    The SearchFilter class will only be applied if the view has a search_fields attribute set. The search_fields attribute should be a list of names of text type fields on the model, such as CharField or TextField.

    @@ -716,7 +716,7 @@ class ProductFilter(django_filters.rest_framework.FilterSet):
    search_fields = ('=username', '=email')
     

    By default, the search parameter is named 'search', but this may be overridden with the SEARCH_PARAM setting.

    -

    For more details, see the Django documentation.

    +

    For more details, see the Django documentation.


    OrderingFilter

    The OrderingFilter class supports simple query parameter controlled ordering of results.

    diff --git a/api-guide/generic-views/index.html b/api-guide/generic-views/index.html index 605ea2bff..43fcf90bf 100644 --- a/api-guide/generic-views/index.html +++ b/api-guide/generic-views/index.html @@ -514,7 +514,7 @@

    Generic views

    Django’s generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.

    -

    Django Documentation

    +

    Django Documentation

    One of the key benefits of class-based views is the way they allow you to compose bits of reusable behavior. REST framework takes advantage of this by providing a number of pre-built views that provide for commonly used patterns.

    The generic views provided by REST framework allow you to quickly build API views that map closely to your database models.

    diff --git a/api-guide/pagination/index.html b/api-guide/pagination/index.html index 216aa17d8..8179e2e7d 100644 --- a/api-guide/pagination/index.html +++ b/api-guide/pagination/index.html @@ -466,7 +466,7 @@

    Pagination

    Django provides a few classes that help you manage paginated data – that is, data that’s split across several pages, with “Previous/Next” links.

    -

    Django documentation

    +

    Django documentation

    REST framework includes support for customizable pagination styles. This allows you to modify how large result sets are split into individual pages of data.

    The pagination API can support either:

    diff --git a/api-guide/parsers/index.html b/api-guide/parsers/index.html index cc80c447f..a1b0f9e73 100644 --- a/api-guide/parsers/index.html +++ b/api-guide/parsers/index.html @@ -537,7 +537,7 @@ def example_view(request, format=None):
    • The FileUploadParser is for usage with native clients that can upload the file as a raw data request. For web-based uploads, or for native clients with multipart upload support, you should use the MultiPartParser parser instead.
    • Since this parser's media_type matches any content type, FileUploadParser should generally be the only parser set on an API view.
    • -
    • FileUploadParser respects Django's standard FILE_UPLOAD_HANDLERS setting, and the request.upload_handlers attribute. See the Django documentation for more details.
    • +
    • FileUploadParser respects Django's standard FILE_UPLOAD_HANDLERS setting, and the request.upload_handlers attribute. See the Django documentation for more details.
    Basic usage example:
    # views.py
    diff --git a/api-guide/permissions/index.html b/api-guide/permissions/index.html
    index 9042ddbdb..83a736eb6 100644
    --- a/api-guide/permissions/index.html
    +++ b/api-guide/permissions/index.html
    @@ -562,7 +562,7 @@ def example_view(request, format=None):
     

    The IsAuthenticatedOrReadOnly will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the "safe" methods; GET, HEAD or OPTIONS.

    This permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users.

    DjangoModelPermissions

    -

    This permission class ties into Django's standard django.contrib.auth model permissions. This permission must only be applied to views that have a .queryset property set. Authorization will only be granted if the user is authenticated and has the relevant model permissions assigned.

    +

    This permission class ties into Django's standard django.contrib.auth model permissions. This permission must only be applied to views that have a .queryset property set. Authorization will only be granted if the user is authenticated and has the relevant model permissions assigned.

    • POST requests require the user to have the add permission on the model.
    • PUT and PATCH requests require the user to have the change permission on the model.
    • @@ -577,7 +577,7 @@ def example_view(request, format=None):

      DjangoModelPermissionsOrAnonReadOnly

      Similar to DjangoModelPermissions, but also allows unauthenticated users to have read-only access to the API.

      DjangoObjectPermissions

      -

      This permission class ties into Django's standard object permissions framework that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as django-guardian.

      +

      This permission class ties into Django's standard object permissions framework that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as django-guardian.

      As with DjangoModelPermissions, this permission must only be applied to views that have a .queryset property or .get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant per-object permissions and relevant model permissions assigned.

      • POST requests require the user to have the add permission on the model instance.
      • @@ -585,7 +585,7 @@ def example_view(request, format=None):
      • DELETE requests require the user to have the delete permission on the model instance.

      Note that DjangoObjectPermissions does not require the django-guardian package, and should support other object-level backends equally well.

      -

      As with DjangoModelPermissions you can use custom model permissions by overriding DjangoModelPermissions and setting the .perms_map property. Refer to the source code for details.

      +

      As with DjangoModelPermissions you can use custom model permissions by overriding DjangoObjectPermissions and setting the .perms_map property. Refer to the source code for details.


      Note: If you need object level view permissions for GET, HEAD and OPTIONS requests, you'll want to consider also adding the DjangoObjectPermissionsFilter class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.


      diff --git a/api-guide/relations/index.html b/api-guide/relations/index.html index 73dffb6d8..4b694e3f1 100644 --- a/api-guide/relations/index.html +++ b/api-guide/relations/index.html @@ -896,7 +896,7 @@ class CustomerHyperlink(serializers.HyperlinkedRelatedField): class Meta: fields = ('track_set', ...)
    -

    See the Django documentation on reverse relationships for more details.

    +

    See the Django documentation on reverse relationships for more details.

    Generic relationships

    If you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want to serialize the targets of the relationship.

    For example, given the following model for a tag, which has a generic relationship with other arbitrary models:

    @@ -904,7 +904,7 @@ class CustomerHyperlink(serializers.HyperlinkedRelatedField): """ Tags arbitrary model instances using a generic relation. - See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/ + See: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/ """ tag_name = models.SlugField() content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) @@ -962,7 +962,7 @@ class Note(models.Model): return serializer.data

    Note that reverse generic keys, expressed using the GenericRelation field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known.

    -

    For more information see the Django documentation on generic relations.

    +

    For more information see the Django documentation on generic relations.

    ManyToManyFields with a Through Model

    By default, relational fields that target a ManyToManyField with a through model specified are set to read-only.

    diff --git a/api-guide/renderers/index.html b/api-guide/renderers/index.html index 67c0fb2f8..e3734815f 100644 --- a/api-guide/renderers/index.html +++ b/api-guide/renderers/index.html @@ -530,7 +530,7 @@

    Renderers

    Before a TemplateResponse instance can be returned to the client, it must be rendered. The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client.

    -

    Django documentation

    +

    Django documentation

    REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types. There is also support for defining your own custom renderers, which gives you the flexibility to design your own media types.

    How the renderer is determined

    @@ -620,6 +620,7 @@ Unlike other renderers, the data passed to the Response does not ne

    You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.

    If you're building websites that use TemplateHTMLRenderer along with other renderer classes, you should consider listing TemplateHTMLRenderer as the first class in the renderer_classes list, so that it will be prioritised first even for browsers that send poorly formed ACCEPT: headers.

    +

    See the HTML & Forms Topic Page for further examples of TemplateHTMLRenderer usage.

    .media_type: text/html

    .format: '.html'

    .charset: utf-8

    @@ -782,7 +783,7 @@ In this case you can underspecify the media types it should respond to, by using

    For good examples of custom media types, see GitHub's use of a custom application/vnd.github+json media type, and Mike Amundsen's IANA approved application/vnd.collection+json JSON-based hypermedia.

    HTML error views

    Typically a renderer will behave the same regardless of if it's dealing with a regular response, or with a response caused by an exception being raised, such as an Http404 or PermissionDenied exception, or a subclass of APIException.

    -

    If you're using either the TemplateHTMLRenderer or the StaticHTMLRenderer and an exception is raised, the behavior is slightly different, and mirrors Django's default handling of error views.

    +

    If you're using either the TemplateHTMLRenderer or the StaticHTMLRenderer and an exception is raised, the behavior is slightly different, and mirrors Django's default handling of error views.

    Exceptions raised and handled by an HTML renderer will attempt to render using one of the following methods, by order of precedence.

    -

    When you're using ModelSerializer all of this is handled automatically for you. If you want to drop down to using a Serializer classes instead, then you need to define the validation rules explicitly.

    +

    When you're using ModelSerializer all of this is handled automatically for you. If you want to drop down to using Serializer classes instead, then you need to define the validation rules explicitly.

    Example

    As an example of how REST framework uses explicit validation, we'll take a simple model class that has a field with a uniqueness constraint.

    class CustomerReportRecord(models.Model):
    @@ -582,11 +582,11 @@ class ExampleSerializer(serializers.Serializer):
     

    The field will not be writable to the user, but the default value will still be passed through to the validated_data.

    Using with a hidden date field.

    -

    If you want the date field to be entirely hidden from the user, then use HiddenField. This field type does not accept user input, but instead always returns it's default value to the validated_data in the serializer.

    +

    If you want the date field to be entirely hidden from the user, then use HiddenField. This field type does not accept user input, but instead always returns its default value to the validated_data in the serializer.

    published = serializers.HiddenField(default=timezone.now)
     

    -

    Note: The UniqueFor<Range>Validation classes always imposes an implicit constraint that the fields they are applied to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.

    +

    Note: The UniqueFor<Range>Validation classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.


    Advanced field defaults

    Validators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that is available as input to the validator.

    diff --git a/index.html b/index.html index fe72bb8ef..a9f827853 100644 --- a/index.html +++ b/index.html @@ -522,7 +522,7 @@ continued development by signing up for a paid diff --git a/mkdocs/search_index.json b/mkdocs/search_index.json index 6ac93e5c1..662f0cb90 100644 --- a/mkdocs/search_index.json +++ b/mkdocs/search_index.json @@ -67,7 +67,7 @@ }, { "location": "/tutorial/quickstart/", - "text": "Quickstart\n\n\nWe're going to create a simple API to allow admin users to view and edit the users and groups in the system.\n\n\nProject setup\n\n\nCreate a new Django project named \ntutorial\n, then start a new app called \nquickstart\n.\n\n\n# Create the project directory\nmkdir tutorial\ncd tutorial\n\n# Create a virtualenv to isolate our package dependencies locally\nvirtualenv env\nsource env/bin/activate # On Windows use `env\\Scripts\\activate`\n\n# Install Django and Django REST framework into the virtualenv\npip install django\npip install djangorestframework\n\n# Set up a new project with a single application\ndjango-admin.py startproject tutorial . # Note the trailing '.' character\ncd tutorial\ndjango-admin.py startapp quickstart\ncd ..\n\n\n\nNow sync your database for the first time:\n\n\npython manage.py migrate\n\n\n\nWe'll also create an initial user named \nadmin\n with a password of \npassword123\n. We'll authenticate as that user later in our example.\n\n\npython manage.py createsuperuser\n\n\n\nOnce you've set up a database and initial user created and ready to go, open up the app's directory and we'll get coding...\n\n\nSerializers\n\n\nFirst up we're going to define some serializers. Let's create a new module named \ntutorial/quickstart/serializers.py\n that we'll use for our data representations.\n\n\nfrom django.contrib.auth.models import User, Group\nfrom rest_framework import serializers\n\n\nclass UserSerializer(serializers.HyperlinkedModelSerializer):\n class Meta:\n model = User\n fields = ('url', 'username', 'email', 'groups')\n\n\nclass GroupSerializer(serializers.HyperlinkedModelSerializer):\n class Meta:\n model = Group\n fields = ('url', 'name')\n\n\n\nNotice that we're using hyperlinked relations in this case, with \nHyperlinkedModelSerializer\n. You can also use primary key and various other relationships, but hyperlinking is good RESTful design.\n\n\nViews\n\n\nRight, we'd better write some views then. Open \ntutorial/quickstart/views.py\n and get typing.\n\n\nfrom django.contrib.auth.models import User, Group\nfrom rest_framework import viewsets\nfrom tutorial.quickstart.serializers import UserSerializer, GroupSerializer\n\n\nclass UserViewSet(viewsets.ModelViewSet):\n \"\"\"\n API endpoint that allows users to be viewed or edited.\n \"\"\"\n queryset = User.objects.all().order_by('-date_joined')\n serializer_class = UserSerializer\n\n\nclass GroupViewSet(viewsets.ModelViewSet):\n \"\"\"\n API endpoint that allows groups to be viewed or edited.\n \"\"\"\n queryset = Group.objects.all()\n serializer_class = GroupSerializer\n\n\n\nRather than write multiple views we're grouping together all the common behavior into classes called \nViewSets\n.\n\n\nWe can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.\n\n\nURLs\n\n\nOkay, now let's wire up the API URLs. On to \ntutorial/urls.py\n...\n\n\nfrom django.conf.urls import url, include\nfrom rest_framework import routers\nfrom tutorial.quickstart import views\n\nrouter = routers.DefaultRouter()\nrouter.register(r'users', views.UserViewSet)\nrouter.register(r'groups', views.GroupViewSet)\n\n# Wire up our API using automatic URL routing.\n# Additionally, we include login URLs for the browsable API.\nurlpatterns = [\n url(r'^', include(router.urls)),\n url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))\n]\n\n\n\nBecause we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class.\n\n\nAgain, if we need more control over the API URLs we can simply drop down to using regular class-based views, and writing the URL conf explicitly.\n\n\nFinally, we're including default login and logout views for use with the browsable API. That's optional, but useful if your API requires authentication and you want to use the browsable API.\n\n\nSettings\n\n\nWe'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users. The settings module will be in \ntutorial/settings.py\n\n\nINSTALLED_APPS = (\n ...\n 'rest_framework',\n)\n\nREST_FRAMEWORK = {\n 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),\n 'PAGE_SIZE': 10\n}\n\n\n\nOkay, we're done.\n\n\n\n\nTesting our API\n\n\nWe're now ready to test the API we've built. Let's fire up the server from the command line.\n\n\npython manage.py runserver\n\n\n\nWe can now access our API, both from the command-line, using tools like \ncurl\n...\n\n\nbash: curl -H 'Accept: application/json; indent=4' -u admin:password123 http://127.0.0.1:8000/users/\n{\n \"count\": 2,\n \"next\": null,\n \"previous\": null,\n \"results\": [\n {\n \"email\": \"admin@example.com\",\n \"groups\": [],\n \"url\": \"http://127.0.0.1:8000/users/1/\",\n \"username\": \"admin\"\n },\n {\n \"email\": \"tom@example.com\",\n \"groups\": [ ],\n \"url\": \"http://127.0.0.1:8000/users/2/\",\n \"username\": \"tom\"\n }\n ]\n}\n\n\n\nOr using the \nhttpie\n, command line tool...\n\n\nbash: http -a admin:password123 http://127.0.0.1:8000/users/\n\nHTTP/1.1 200 OK\n...\n{\n \"count\": 2,\n \"next\": null,\n \"previous\": null,\n \"results\": [\n {\n \"email\": \"admin@example.com\",\n \"groups\": [],\n \"url\": \"http://localhost:8000/users/1/\",\n \"username\": \"paul\"\n },\n {\n \"email\": \"tom@example.com\",\n \"groups\": [ ],\n \"url\": \"http://127.0.0.1:8000/users/2/\",\n \"username\": \"tom\"\n }\n ]\n}\n\n\n\nOr directly through the browser, by going to the URL \nhttp://127.0.0.1:8000/users/\n...\n\n\n\n\nIf you're working through the browser, make sure to login using the control in the top right corner.\n\n\nGreat, that was easy!\n\n\nIf you want to get a more in depth understanding of how REST framework fits together head on over to \nthe tutorial\n, or start browsing the \nAPI guide\n.", + "text": "Quickstart\n\n\nWe're going to create a simple API to allow admin users to view and edit the users and groups in the system.\n\n\nProject setup\n\n\nCreate a new Django project named \ntutorial\n, then start a new app called \nquickstart\n.\n\n\n# Create the project directory\nmkdir tutorial\ncd tutorial\n\n# Create a virtualenv to isolate our package dependencies locally\nvirtualenv env\nsource env/bin/activate # On Windows use `env\\Scripts\\activate`\n\n# Install Django and Django REST framework into the virtualenv\npip install django\npip install djangorestframework\n\n# Set up a new project with a single application\ndjango-admin.py startproject tutorial . # Note the trailing '.' character\ncd tutorial\ndjango-admin.py startapp quickstart\ncd ..\n\n\n\nNow sync your database for the first time:\n\n\npython manage.py migrate\n\n\n\nWe'll also create an initial user named \nadmin\n with a password of \npassword123\n. We'll authenticate as that user later in our example.\n\n\npython manage.py createsuperuser\n\n\n\nOnce you've set up a database and initial user created and ready to go, open up the app's directory and we'll get coding...\n\n\nSerializers\n\n\nFirst up we're going to define some serializers. Let's create a new module named \ntutorial/quickstart/serializers.py\n that we'll use for our data representations.\n\n\nfrom django.contrib.auth.models import User, Group\nfrom rest_framework import serializers\n\n\nclass UserSerializer(serializers.HyperlinkedModelSerializer):\n class Meta:\n model = User\n fields = ('url', 'username', 'email', 'groups')\n\n\nclass GroupSerializer(serializers.HyperlinkedModelSerializer):\n class Meta:\n model = Group\n fields = ('url', 'name')\n\n\n\nNotice that we're using hyperlinked relations in this case, with \nHyperlinkedModelSerializer\n. You can also use primary key and various other relationships, but hyperlinking is good RESTful design.\n\n\nViews\n\n\nRight, we'd better write some views then. Open \ntutorial/quickstart/views.py\n and get typing.\n\n\nfrom django.contrib.auth.models import User, Group\nfrom rest_framework import viewsets\nfrom tutorial.quickstart.serializers import UserSerializer, GroupSerializer\n\n\nclass UserViewSet(viewsets.ModelViewSet):\n \"\"\"\n API endpoint that allows users to be viewed or edited.\n \"\"\"\n queryset = User.objects.all().order_by('-date_joined')\n serializer_class = UserSerializer\n\n\nclass GroupViewSet(viewsets.ModelViewSet):\n \"\"\"\n API endpoint that allows groups to be viewed or edited.\n \"\"\"\n queryset = Group.objects.all()\n serializer_class = GroupSerializer\n\n\n\nRather than write multiple views we're grouping together all the common behavior into classes called \nViewSets\n.\n\n\nWe can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.\n\n\nURLs\n\n\nOkay, now let's wire up the API URLs. On to \ntutorial/urls.py\n...\n\n\nfrom django.conf.urls import url, include\nfrom rest_framework import routers\nfrom tutorial.quickstart import views\n\nrouter = routers.DefaultRouter()\nrouter.register(r'users', views.UserViewSet)\nrouter.register(r'groups', views.GroupViewSet)\n\n# Wire up our API using automatic URL routing.\n# Additionally, we include login URLs for the browsable API.\nurlpatterns = [\n url(r'^', include(router.urls)),\n url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))\n]\n\n\n\nBecause we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class.\n\n\nAgain, if we need more control over the API URLs we can simply drop down to using regular class-based views, and writing the URL conf explicitly.\n\n\nFinally, we're including default login and logout views for use with the browsable API. That's optional, but useful if your API requires authentication and you want to use the browsable API.\n\n\nSettings\n\n\nWe'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users. The settings module will be in \ntutorial/settings.py\n\n\nINSTALLED_APPS = (\n ...\n 'rest_framework',\n)\n\nREST_FRAMEWORK = {\n 'DEFAULT_PERMISSION_CLASSES': [\n 'rest_framework.permissions.IsAdminUser',\n ],\n 'PAGE_SIZE': 10\n}\n\n\n\nOkay, we're done.\n\n\n\n\nTesting our API\n\n\nWe're now ready to test the API we've built. Let's fire up the server from the command line.\n\n\npython manage.py runserver\n\n\n\nWe can now access our API, both from the command-line, using tools like \ncurl\n...\n\n\nbash: curl -H 'Accept: application/json; indent=4' -u admin:password123 http://127.0.0.1:8000/users/\n{\n \"count\": 2,\n \"next\": null,\n \"previous\": null,\n \"results\": [\n {\n \"email\": \"admin@example.com\",\n \"groups\": [],\n \"url\": \"http://127.0.0.1:8000/users/1/\",\n \"username\": \"admin\"\n },\n {\n \"email\": \"tom@example.com\",\n \"groups\": [ ],\n \"url\": \"http://127.0.0.1:8000/users/2/\",\n \"username\": \"tom\"\n }\n ]\n}\n\n\n\nOr using the \nhttpie\n, command line tool...\n\n\nbash: http -a admin:password123 http://127.0.0.1:8000/users/\n\nHTTP/1.1 200 OK\n...\n{\n \"count\": 2,\n \"next\": null,\n \"previous\": null,\n \"results\": [\n {\n \"email\": \"admin@example.com\",\n \"groups\": [],\n \"url\": \"http://localhost:8000/users/1/\",\n \"username\": \"paul\"\n },\n {\n \"email\": \"tom@example.com\",\n \"groups\": [ ],\n \"url\": \"http://127.0.0.1:8000/users/2/\",\n \"username\": \"tom\"\n }\n ]\n}\n\n\n\nOr directly through the browser, by going to the URL \nhttp://127.0.0.1:8000/users/\n...\n\n\n\n\nIf you're working through the browser, make sure to login using the control in the top right corner.\n\n\nGreat, that was easy!\n\n\nIf you want to get a more in depth understanding of how REST framework fits together head on over to \nthe tutorial\n, or start browsing the \nAPI guide\n.", "title": "Quickstart" }, { @@ -97,7 +97,7 @@ }, { "location": "/tutorial/quickstart/#settings", - "text": "We'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users. The settings module will be in tutorial/settings.py INSTALLED_APPS = (\n ...\n 'rest_framework',\n)\n\nREST_FRAMEWORK = {\n 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),\n 'PAGE_SIZE': 10\n} Okay, we're done.", + "text": "We'd also like to set a few global settings. We'd like to turn on pagination, and we want our API to only be accessible to admin users. The settings module will be in tutorial/settings.py INSTALLED_APPS = (\n ...\n 'rest_framework',\n)\n\nREST_FRAMEWORK = {\n 'DEFAULT_PERMISSION_CLASSES': [\n 'rest_framework.permissions.IsAdminUser',\n ],\n 'PAGE_SIZE': 10\n} Okay, we're done.", "title": "Settings" }, { @@ -1142,7 +1142,7 @@ }, { "location": "/api-guide/renderers/", - "text": "Renderers\n\n\n\n\nBefore a TemplateResponse instance can be returned to the client, it must be rendered. The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client.\n\n\n \nDjango documentation\n\n\n\n\nREST framework includes a number of built in Renderer classes, that allow you to return responses with various media types. There is also support for defining your own custom renderers, which gives you the flexibility to design your own media types.\n\n\nHow the renderer is determined\n\n\nThe set of valid renderers for a view is always defined as a list of classes. When a view is entered REST framework will perform content negotiation on the incoming request, and determine the most appropriate renderer to satisfy the request.\n\n\nThe basic process of content negotiation involves examining the request's \nAccept\n header, to determine which media types it expects in the response. Optionally, format suffixes on the URL may be used to explicitly request a particular representation. For example the URL \nhttp://example.com/api/users_count.json\n might be an endpoint that always returns JSON data.\n\n\nFor more information see the documentation on \ncontent negotiation\n.\n\n\nSetting the renderers\n\n\nThe default set of renderers may be set globally, using the \nDEFAULT_RENDERER_CLASSES\n setting. For example, the following settings would use \nJSON\n as the main media type and also include the self describing API.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework.renderers.JSONRenderer',\n 'rest_framework.renderers.BrowsableAPIRenderer',\n )\n}\n\n\n\nYou can also set the renderers used for an individual view, or viewset,\nusing the \nAPIView\n class-based views.\n\n\nfrom django.contrib.auth.models import User\nfrom rest_framework.renderers import JSONRenderer\nfrom rest_framework.response import Response\nfrom rest_framework.views import APIView\n\nclass UserCountView(APIView):\n \"\"\"\n A view that returns the count of active users in JSON.\n \"\"\"\n renderer_classes = (JSONRenderer, )\n\n def get(self, request, format=None):\n user_count = User.objects.filter(active=True).count()\n content = {'user_count': user_count}\n return Response(content)\n\n\n\nOr, if you're using the \n@api_view\n decorator with function based views.\n\n\n@api_view(['GET'])\n@renderer_classes((JSONRenderer,))\ndef user_count_view(request, format=None):\n \"\"\"\n A view that returns the count of active users in JSON.\n \"\"\"\n user_count = User.objects.filter(active=True).count()\n content = {'user_count': user_count}\n return Response(content)\n\n\n\nOrdering of renderer classes\n\n\nIt's important when specifying the renderer classes for your API to think about what priority you want to assign to each media type. If a client underspecifies the representations it can accept, such as sending an \nAccept: */*\n header, or not including an \nAccept\n header at all, then REST framework will select the first renderer in the list to use for the response.\n\n\nFor example if your API serves JSON responses and the HTML browsable API, you might want to make \nJSONRenderer\n your default renderer, in order to send \nJSON\n responses to clients that do not specify an \nAccept\n header.\n\n\nIf your API includes views that can serve both regular webpages and API responses depending on the request, then you might consider making \nTemplateHTMLRenderer\n your default renderer, in order to play nicely with older browsers that send \nbroken accept headers\n.\n\n\n\n\nAPI Reference\n\n\nJSONRenderer\n\n\nRenders the request data into \nJSON\n, using utf-8 encoding.\n\n\nNote that the default style is to include unicode characters, and render the response using a compact style with no unnecessary whitespace:\n\n\n{\"unicode black star\":\"\u2605\",\"value\":999}\n\n\n\nThe client may additionally include an \n'indent'\n media type parameter, in which case the returned \nJSON\n will be indented. For example \nAccept: application/json; indent=4\n.\n\n\n{\n \"unicode black star\": \"\u2605\",\n \"value\": 999\n}\n\n\n\nThe default JSON encoding style can be altered using the \nUNICODE_JSON\n and \nCOMPACT_JSON\n settings keys.\n\n\n.media_type\n: \napplication/json\n\n\n.format\n: \n'.json'\n\n\n.charset\n: \nNone\n\n\nTemplateHTMLRenderer\n\n\nRenders data to HTML, using Django's standard template rendering.\nUnlike other renderers, the data passed to the \nResponse\n does not need to be serialized. Also, unlike other renderers, you may want to include a \ntemplate_name\n argument when creating the \nResponse\n.\n\n\nThe TemplateHTMLRenderer will create a \nRequestContext\n, using the \nresponse.data\n as the context dict, and determine a template name to use to render the context.\n\n\nThe template name is determined by (in order of preference):\n\n\n\n\nAn explicit \ntemplate_name\n argument passed to the response.\n\n\nAn explicit \n.template_name\n attribute set on this class.\n\n\nThe return result of calling \nview.get_template_names()\n.\n\n\n\n\nAn example of a view that uses \nTemplateHTMLRenderer\n:\n\n\nclass UserDetail(generics.RetrieveAPIView):\n \"\"\"\n A view that returns a templated HTML representation of a given user.\n \"\"\"\n queryset = User.objects.all()\n renderer_classes = (TemplateHTMLRenderer,)\n\n def get(self, request, *args, **kwargs):\n self.object = self.get_object()\n return Response({'user': self.object}, template_name='user_detail.html')\n\n\n\nYou can use \nTemplateHTMLRenderer\n either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.\n\n\nIf you're building websites that use \nTemplateHTMLRenderer\n along with other renderer classes, you should consider listing \nTemplateHTMLRenderer\n as the first class in the \nrenderer_classes\n list, so that it will be prioritised first even for browsers that send poorly formed \nACCEPT:\n headers.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.html'\n\n\n.charset\n: \nutf-8\n\n\nSee also: \nStaticHTMLRenderer\n\n\nStaticHTMLRenderer\n\n\nA simple renderer that simply returns pre-rendered HTML. Unlike other renderers, the data passed to the response object should be a string representing the content to be returned.\n\n\nAn example of a view that uses \nStaticHTMLRenderer\n:\n\n\n@api_view(('GET',))\n@renderer_classes((StaticHTMLRenderer,))\ndef simple_html_view(request):\n data = '\nhtml\nbody\nh1\nHello, world\n/h1\n/body\n/html\n'\n return Response(data)\n\n\n\nYou can use \nStaticHTMLRenderer\n either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.html'\n\n\n.charset\n: \nutf-8\n\n\nSee also: \nTemplateHTMLRenderer\n\n\nBrowsableAPIRenderer\n\n\nRenders data into HTML for the Browsable API:\n\n\n\n\nThis renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.api'\n\n\n.charset\n: \nutf-8\n\n\n.template\n: \n'rest_framework/api.html'\n\n\nCustomizing BrowsableAPIRenderer\n\n\nBy default the response content will be rendered with the highest priority renderer apart from \nBrowsableAPIRenderer\n. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the \nget_default_renderer()\n method. For example:\n\n\nclass CustomBrowsableAPIRenderer(BrowsableAPIRenderer):\n def get_default_renderer(self, view):\n return JSONRenderer()\n\n\n\nAdminRenderer\n\n\nRenders data into HTML for an admin-like display:\n\n\n\n\nThis renderer is suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data.\n\n\nNote that views that have nested or list serializers for their input won't work well with the \nAdminRenderer\n, as the HTML forms are unable to properly support them.\n\n\nNote\n: The \nAdminRenderer\n is only able to include links to detail pages when a properly configured \nURL_FIELD_NAME\n (\nurl\n by default) attribute is present in the data. For \nHyperlinkedModelSerializer\n this will be the case, but for \nModelSerializer\n or plain \nSerializer\n classes you'll need to make sure to include the field explicitly. For example here we use models \nget_absolute_url\n method:\n\n\nclass AccountSerializer(serializers.ModelSerializer):\n url = serializers.CharField(source='get_absolute_url', read_only=True)\n\n class Meta:\n model = Account\n\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.admin'\n\n\n.charset\n: \nutf-8\n\n\n.template\n: \n'rest_framework/admin.html'\n\n\nHTMLFormRenderer\n\n\nRenders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing \nform\n tags, a hidden CSRF input or any submit buttons.\n\n\nThis renderer is not intended to be used directly, but can instead be used in templates by passing a serializer instance to the \nrender_form\n template tag.\n\n\n{% load rest_framework %}\n\n\nform action=\"/submit-report/\" method=\"post\"\n\n {% csrf_token %}\n {% render_form serializer %}\n \ninput type=\"submit\" value=\"Save\" /\n\n\n/form\n\n\n\n\nFor more information see the \nHTML \n Forms\n documentation.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.form'\n\n\n.charset\n: \nutf-8\n\n\n.template\n: \n'rest_framework/horizontal/form.html'\n\n\nMultiPartRenderer\n\n\nThis renderer is used for rendering HTML multipart form data. \nIt is not suitable as a response renderer\n, but is instead used for creating test requests, using REST framework's \ntest client and test request factory\n.\n\n\n.media_type\n: \nmultipart/form-data; boundary=BoUnDaRyStRiNg\n\n\n.format\n: \n'.multipart'\n\n\n.charset\n: \nutf-8\n\n\n\n\nCustom renderers\n\n\nTo implement a custom renderer, you should override \nBaseRenderer\n, set the \n.media_type\n and \n.format\n properties, and implement the \n.render(self, data, media_type=None, renderer_context=None)\n method.\n\n\nThe method should return a bytestring, which will be used as the body of the HTTP response.\n\n\nThe arguments passed to the \n.render()\n method are:\n\n\ndata\n\n\nThe request data, as set by the \nResponse()\n instantiation.\n\n\nmedia_type=None\n\n\nOptional. If provided, this is the accepted media type, as determined by the content negotiation stage.\n\n\nDepending on the client's \nAccept:\n header, this may be more specific than the renderer's \nmedia_type\n attribute, and may include media type parameters. For example \n\"application/json; nested=true\"\n.\n\n\nrenderer_context=None\n\n\nOptional. If provided, this is a dictionary of contextual information provided by the view.\n\n\nBy default this will include the following keys: \nview\n, \nrequest\n, \nresponse\n, \nargs\n, \nkwargs\n.\n\n\nExample\n\n\nThe following is an example plaintext renderer that will return a response with the \ndata\n parameter as the content of the response.\n\n\nfrom django.utils.encoding import smart_unicode\nfrom rest_framework import renderers\n\n\nclass PlainTextRenderer(renderers.BaseRenderer):\n media_type = 'text/plain'\n format = 'txt'\n\n def render(self, data, media_type=None, renderer_context=None):\n return data.encode(self.charset)\n\n\n\nSetting the character set\n\n\nBy default renderer classes are assumed to be using the \nUTF-8\n encoding. To use a different encoding, set the \ncharset\n attribute on the renderer.\n\n\nclass PlainTextRenderer(renderers.BaseRenderer):\n media_type = 'text/plain'\n format = 'txt'\n charset = 'iso-8859-1'\n\n def render(self, data, media_type=None, renderer_context=None):\n return data.encode(self.charset)\n\n\n\nNote that if a renderer class returns a unicode string, then the response content will be coerced into a bytestring by the \nResponse\n class, with the \ncharset\n attribute set on the renderer used to determine the encoding.\n\n\nIf the renderer returns a bytestring representing raw binary content, you should set a charset value of \nNone\n, which will ensure the \nContent-Type\n header of the response will not have a \ncharset\n value set.\n\n\nIn some cases you may also want to set the \nrender_style\n attribute to \n'binary'\n. Doing so will also ensure that the browsable API will not attempt to display the binary content as a string.\n\n\nclass JPEGRenderer(renderers.BaseRenderer):\n media_type = 'image/jpeg'\n format = 'jpg'\n charset = None\n render_style = 'binary'\n\n def render(self, data, media_type=None, renderer_context=None):\n return data\n\n\n\n\n\nAdvanced renderer usage\n\n\nYou can do some pretty flexible things using REST framework's renderers. Some examples...\n\n\n\n\nProvide either flat or nested representations from the same endpoint, depending on the requested media type.\n\n\nServe both regular HTML webpages, and JSON based API responses from the same endpoints.\n\n\nSpecify multiple types of HTML representation for API clients to use.\n\n\nUnderspecify a renderer's media type, such as using \nmedia_type = 'image/*'\n, and use the \nAccept\n header to vary the encoding of the response.\n\n\n\n\nVarying behaviour by media type\n\n\nIn some cases you might want your view to use different serialization styles depending on the accepted media type. If you need to do this you can access \nrequest.accepted_renderer\n to determine the negotiated renderer that will be used for the response.\n\n\nFor example:\n\n\n@api_view(('GET',))\n@renderer_classes((TemplateHTMLRenderer, JSONRenderer))\ndef list_users(request):\n \"\"\"\n A view that can return JSON or HTML representations\n of the users in the system.\n \"\"\"\n queryset = Users.objects.filter(active=True)\n\n if request.accepted_renderer.format == 'html':\n # TemplateHTMLRenderer takes a context dict,\n # and additionally requires a 'template_name'.\n # It does not require serialization.\n data = {'users': queryset}\n return Response(data, template_name='list_users.html')\n\n # JSONRenderer requires serialized data as normal.\n serializer = UserSerializer(instance=queryset)\n data = serializer.data\n return Response(data)\n\n\n\nUnderspecifying the media type\n\n\nIn some cases you might want a renderer to serve a range of media types.\nIn this case you can underspecify the media types it should respond to, by using a \nmedia_type\n value such as \nimage/*\n, or \n*/*\n.\n\n\nIf you underspecify the renderer's media type, you should make sure to specify the media type explicitly when you return the response, using the \ncontent_type\n attribute. For example:\n\n\nreturn Response(data, content_type='image/png')\n\n\n\nDesigning your media types\n\n\nFor the purposes of many Web APIs, simple \nJSON\n responses with hyperlinked relations may be sufficient. If you want to fully embrace RESTful design and \nHATEOAS\n you'll need to consider the design and usage of your media types in more detail.\n\n\nIn \nthe words of Roy Fielding\n, \"A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.\".\n\n\nFor good examples of custom media types, see GitHub's use of a custom \napplication/vnd.github+json\n media type, and Mike Amundsen's IANA approved \napplication/vnd.collection+json\n JSON-based hypermedia.\n\n\nHTML error views\n\n\nTypically a renderer will behave the same regardless of if it's dealing with a regular response, or with a response caused by an exception being raised, such as an \nHttp404\n or \nPermissionDenied\n exception, or a subclass of \nAPIException\n.\n\n\nIf you're using either the \nTemplateHTMLRenderer\n or the \nStaticHTMLRenderer\n and an exception is raised, the behavior is slightly different, and mirrors \nDjango's default handling of error views\n.\n\n\nExceptions raised and handled by an HTML renderer will attempt to render using one of the following methods, by order of precedence.\n\n\n\n\nLoad and render a template named \n{status_code}.html\n.\n\n\nLoad and render a template named \napi_exception.html\n.\n\n\nRender the HTTP status code and text, for example \"404 Not Found\".\n\n\n\n\nTemplates will render with a \nRequestContext\n which includes the \nstatus_code\n and \ndetails\n keys.\n\n\nNote\n: If \nDEBUG=True\n, Django's standard traceback error page will be displayed instead of rendering the HTTP status code and text.\n\n\n\n\nThird party packages\n\n\nThe following third party packages are also available.\n\n\nYAML\n\n\nREST framework YAML\n provides \nYAML\n parsing and rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.\n\n\nInstallation \n configuration\n\n\nInstall using pip.\n\n\n$ pip install djangorestframework-yaml\n\n\n\nModify your REST framework settings.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_PARSER_CLASSES': (\n 'rest_framework_yaml.parsers.YAMLParser',\n ),\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework_yaml.renderers.YAMLRenderer',\n ),\n}\n\n\n\nXML\n\n\nREST Framework XML\n provides a simple informal XML format. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.\n\n\nInstallation \n configuration\n\n\nInstall using pip.\n\n\n$ pip install djangorestframework-xml\n\n\n\nModify your REST framework settings.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_PARSER_CLASSES': (\n 'rest_framework_xml.parsers.XMLParser',\n ),\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework_xml.renderers.XMLRenderer',\n ),\n}\n\n\n\nJSONP\n\n\nREST framework JSONP\n provides JSONP rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.\n\n\n\n\nWarning\n: If you require cross-domain AJAX requests, you should generally be using the more modern approach of \nCORS\n as an alternative to \nJSONP\n. See the \nCORS documentation\n for more details.\n\n\nThe \njsonp\n approach is essentially a browser hack, and is \nonly appropriate for globally readable API endpoints\n, where \nGET\n requests are unauthenticated and do not require any user permissions.\n\n\n\n\nInstallation \n configuration\n\n\nInstall using pip.\n\n\n$ pip install djangorestframework-jsonp\n\n\n\nModify your REST framework settings.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework_jsonp.renderers.JSONPRenderer',\n ),\n}\n\n\n\nMessagePack\n\n\nMessagePack\n is a fast, efficient binary serialization format. \nJuan Riaza\n maintains the \ndjangorestframework-msgpack\n package which provides MessagePack renderer and parser support for REST framework.\n\n\nCSV\n\n\nComma-separated values are a plain-text tabular data format, that can be easily imported into spreadsheet applications. \nMjumbe Poe\n maintains the \ndjangorestframework-csv\n package which provides CSV renderer support for REST framework.\n\n\nUltraJSON\n\n\nUltraJSON\n is an optimized C JSON encoder which can give significantly faster JSON rendering. \nJacob Haslehurst\n maintains the \ndrf-ujson-renderer\n package which implements JSON rendering using the UJSON package.\n\n\nCamelCase JSON\n\n\ndjangorestframework-camel-case\n provides camel case JSON renderers and parsers for REST framework. This allows serializers to use Python-style underscored field names, but be exposed in the API as Javascript-style camel case field names. It is maintained by \nVitaly Babiy\n.\n\n\nPandas (CSV, Excel, PNG)\n\n\nDjango REST Pandas\n provides a serializer and renderers that support additional data processing and output via the \nPandas\n DataFrame API. Django REST Pandas includes renderers for Pandas-style CSV files, Excel workbooks (both \n.xls\n and \n.xlsx\n), and a number of \nother formats\n. It is maintained by \nS. Andrew Sheppard\n as part of the \nwq Project\n.\n\n\nLaTeX\n\n\nRest Framework Latex\n provides a renderer that outputs PDFs using Laulatex. It is maintained by \nPebble (S/F Software)\n.", + "text": "Renderers\n\n\n\n\nBefore a TemplateResponse instance can be returned to the client, it must be rendered. The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client.\n\n\n \nDjango documentation\n\n\n\n\nREST framework includes a number of built in Renderer classes, that allow you to return responses with various media types. There is also support for defining your own custom renderers, which gives you the flexibility to design your own media types.\n\n\nHow the renderer is determined\n\n\nThe set of valid renderers for a view is always defined as a list of classes. When a view is entered REST framework will perform content negotiation on the incoming request, and determine the most appropriate renderer to satisfy the request.\n\n\nThe basic process of content negotiation involves examining the request's \nAccept\n header, to determine which media types it expects in the response. Optionally, format suffixes on the URL may be used to explicitly request a particular representation. For example the URL \nhttp://example.com/api/users_count.json\n might be an endpoint that always returns JSON data.\n\n\nFor more information see the documentation on \ncontent negotiation\n.\n\n\nSetting the renderers\n\n\nThe default set of renderers may be set globally, using the \nDEFAULT_RENDERER_CLASSES\n setting. For example, the following settings would use \nJSON\n as the main media type and also include the self describing API.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework.renderers.JSONRenderer',\n 'rest_framework.renderers.BrowsableAPIRenderer',\n )\n}\n\n\n\nYou can also set the renderers used for an individual view, or viewset,\nusing the \nAPIView\n class-based views.\n\n\nfrom django.contrib.auth.models import User\nfrom rest_framework.renderers import JSONRenderer\nfrom rest_framework.response import Response\nfrom rest_framework.views import APIView\n\nclass UserCountView(APIView):\n \"\"\"\n A view that returns the count of active users in JSON.\n \"\"\"\n renderer_classes = (JSONRenderer, )\n\n def get(self, request, format=None):\n user_count = User.objects.filter(active=True).count()\n content = {'user_count': user_count}\n return Response(content)\n\n\n\nOr, if you're using the \n@api_view\n decorator with function based views.\n\n\n@api_view(['GET'])\n@renderer_classes((JSONRenderer,))\ndef user_count_view(request, format=None):\n \"\"\"\n A view that returns the count of active users in JSON.\n \"\"\"\n user_count = User.objects.filter(active=True).count()\n content = {'user_count': user_count}\n return Response(content)\n\n\n\nOrdering of renderer classes\n\n\nIt's important when specifying the renderer classes for your API to think about what priority you want to assign to each media type. If a client underspecifies the representations it can accept, such as sending an \nAccept: */*\n header, or not including an \nAccept\n header at all, then REST framework will select the first renderer in the list to use for the response.\n\n\nFor example if your API serves JSON responses and the HTML browsable API, you might want to make \nJSONRenderer\n your default renderer, in order to send \nJSON\n responses to clients that do not specify an \nAccept\n header.\n\n\nIf your API includes views that can serve both regular webpages and API responses depending on the request, then you might consider making \nTemplateHTMLRenderer\n your default renderer, in order to play nicely with older browsers that send \nbroken accept headers\n.\n\n\n\n\nAPI Reference\n\n\nJSONRenderer\n\n\nRenders the request data into \nJSON\n, using utf-8 encoding.\n\n\nNote that the default style is to include unicode characters, and render the response using a compact style with no unnecessary whitespace:\n\n\n{\"unicode black star\":\"\u2605\",\"value\":999}\n\n\n\nThe client may additionally include an \n'indent'\n media type parameter, in which case the returned \nJSON\n will be indented. For example \nAccept: application/json; indent=4\n.\n\n\n{\n \"unicode black star\": \"\u2605\",\n \"value\": 999\n}\n\n\n\nThe default JSON encoding style can be altered using the \nUNICODE_JSON\n and \nCOMPACT_JSON\n settings keys.\n\n\n.media_type\n: \napplication/json\n\n\n.format\n: \n'.json'\n\n\n.charset\n: \nNone\n\n\nTemplateHTMLRenderer\n\n\nRenders data to HTML, using Django's standard template rendering.\nUnlike other renderers, the data passed to the \nResponse\n does not need to be serialized. Also, unlike other renderers, you may want to include a \ntemplate_name\n argument when creating the \nResponse\n.\n\n\nThe TemplateHTMLRenderer will create a \nRequestContext\n, using the \nresponse.data\n as the context dict, and determine a template name to use to render the context.\n\n\nThe template name is determined by (in order of preference):\n\n\n\n\nAn explicit \ntemplate_name\n argument passed to the response.\n\n\nAn explicit \n.template_name\n attribute set on this class.\n\n\nThe return result of calling \nview.get_template_names()\n.\n\n\n\n\nAn example of a view that uses \nTemplateHTMLRenderer\n:\n\n\nclass UserDetail(generics.RetrieveAPIView):\n \"\"\"\n A view that returns a templated HTML representation of a given user.\n \"\"\"\n queryset = User.objects.all()\n renderer_classes = (TemplateHTMLRenderer,)\n\n def get(self, request, *args, **kwargs):\n self.object = self.get_object()\n return Response({'user': self.object}, template_name='user_detail.html')\n\n\n\nYou can use \nTemplateHTMLRenderer\n either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.\n\n\nIf you're building websites that use \nTemplateHTMLRenderer\n along with other renderer classes, you should consider listing \nTemplateHTMLRenderer\n as the first class in the \nrenderer_classes\n list, so that it will be prioritised first even for browsers that send poorly formed \nACCEPT:\n headers.\n\n\nSee the \nHTML \n Forms\n Topic Page\n for further examples of \nTemplateHTMLRenderer\n usage.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.html'\n\n\n.charset\n: \nutf-8\n\n\nSee also: \nStaticHTMLRenderer\n\n\nStaticHTMLRenderer\n\n\nA simple renderer that simply returns pre-rendered HTML. Unlike other renderers, the data passed to the response object should be a string representing the content to be returned.\n\n\nAn example of a view that uses \nStaticHTMLRenderer\n:\n\n\n@api_view(('GET',))\n@renderer_classes((StaticHTMLRenderer,))\ndef simple_html_view(request):\n data = '\nhtml\nbody\nh1\nHello, world\n/h1\n/body\n/html\n'\n return Response(data)\n\n\n\nYou can use \nStaticHTMLRenderer\n either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.html'\n\n\n.charset\n: \nutf-8\n\n\nSee also: \nTemplateHTMLRenderer\n\n\nBrowsableAPIRenderer\n\n\nRenders data into HTML for the Browsable API:\n\n\n\n\nThis renderer will determine which other renderer would have been given highest priority, and use that to display an API style response within the HTML page.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.api'\n\n\n.charset\n: \nutf-8\n\n\n.template\n: \n'rest_framework/api.html'\n\n\nCustomizing BrowsableAPIRenderer\n\n\nBy default the response content will be rendered with the highest priority renderer apart from \nBrowsableAPIRenderer\n. If you need to customize this behavior, for example to use HTML as the default return format, but use JSON in the browsable API, you can do so by overriding the \nget_default_renderer()\n method. For example:\n\n\nclass CustomBrowsableAPIRenderer(BrowsableAPIRenderer):\n def get_default_renderer(self, view):\n return JSONRenderer()\n\n\n\nAdminRenderer\n\n\nRenders data into HTML for an admin-like display:\n\n\n\n\nThis renderer is suitable for CRUD-style web APIs that should also present a user-friendly interface for managing the data.\n\n\nNote that views that have nested or list serializers for their input won't work well with the \nAdminRenderer\n, as the HTML forms are unable to properly support them.\n\n\nNote\n: The \nAdminRenderer\n is only able to include links to detail pages when a properly configured \nURL_FIELD_NAME\n (\nurl\n by default) attribute is present in the data. For \nHyperlinkedModelSerializer\n this will be the case, but for \nModelSerializer\n or plain \nSerializer\n classes you'll need to make sure to include the field explicitly. For example here we use models \nget_absolute_url\n method:\n\n\nclass AccountSerializer(serializers.ModelSerializer):\n url = serializers.CharField(source='get_absolute_url', read_only=True)\n\n class Meta:\n model = Account\n\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.admin'\n\n\n.charset\n: \nutf-8\n\n\n.template\n: \n'rest_framework/admin.html'\n\n\nHTMLFormRenderer\n\n\nRenders data returned by a serializer into an HTML form. The output of this renderer does not include the enclosing \nform\n tags, a hidden CSRF input or any submit buttons.\n\n\nThis renderer is not intended to be used directly, but can instead be used in templates by passing a serializer instance to the \nrender_form\n template tag.\n\n\n{% load rest_framework %}\n\n\nform action=\"/submit-report/\" method=\"post\"\n\n {% csrf_token %}\n {% render_form serializer %}\n \ninput type=\"submit\" value=\"Save\" /\n\n\n/form\n\n\n\n\nFor more information see the \nHTML \n Forms\n documentation.\n\n\n.media_type\n: \ntext/html\n\n\n.format\n: \n'.form'\n\n\n.charset\n: \nutf-8\n\n\n.template\n: \n'rest_framework/horizontal/form.html'\n\n\nMultiPartRenderer\n\n\nThis renderer is used for rendering HTML multipart form data. \nIt is not suitable as a response renderer\n, but is instead used for creating test requests, using REST framework's \ntest client and test request factory\n.\n\n\n.media_type\n: \nmultipart/form-data; boundary=BoUnDaRyStRiNg\n\n\n.format\n: \n'.multipart'\n\n\n.charset\n: \nutf-8\n\n\n\n\nCustom renderers\n\n\nTo implement a custom renderer, you should override \nBaseRenderer\n, set the \n.media_type\n and \n.format\n properties, and implement the \n.render(self, data, media_type=None, renderer_context=None)\n method.\n\n\nThe method should return a bytestring, which will be used as the body of the HTTP response.\n\n\nThe arguments passed to the \n.render()\n method are:\n\n\ndata\n\n\nThe request data, as set by the \nResponse()\n instantiation.\n\n\nmedia_type=None\n\n\nOptional. If provided, this is the accepted media type, as determined by the content negotiation stage.\n\n\nDepending on the client's \nAccept:\n header, this may be more specific than the renderer's \nmedia_type\n attribute, and may include media type parameters. For example \n\"application/json; nested=true\"\n.\n\n\nrenderer_context=None\n\n\nOptional. If provided, this is a dictionary of contextual information provided by the view.\n\n\nBy default this will include the following keys: \nview\n, \nrequest\n, \nresponse\n, \nargs\n, \nkwargs\n.\n\n\nExample\n\n\nThe following is an example plaintext renderer that will return a response with the \ndata\n parameter as the content of the response.\n\n\nfrom django.utils.encoding import smart_unicode\nfrom rest_framework import renderers\n\n\nclass PlainTextRenderer(renderers.BaseRenderer):\n media_type = 'text/plain'\n format = 'txt'\n\n def render(self, data, media_type=None, renderer_context=None):\n return data.encode(self.charset)\n\n\n\nSetting the character set\n\n\nBy default renderer classes are assumed to be using the \nUTF-8\n encoding. To use a different encoding, set the \ncharset\n attribute on the renderer.\n\n\nclass PlainTextRenderer(renderers.BaseRenderer):\n media_type = 'text/plain'\n format = 'txt'\n charset = 'iso-8859-1'\n\n def render(self, data, media_type=None, renderer_context=None):\n return data.encode(self.charset)\n\n\n\nNote that if a renderer class returns a unicode string, then the response content will be coerced into a bytestring by the \nResponse\n class, with the \ncharset\n attribute set on the renderer used to determine the encoding.\n\n\nIf the renderer returns a bytestring representing raw binary content, you should set a charset value of \nNone\n, which will ensure the \nContent-Type\n header of the response will not have a \ncharset\n value set.\n\n\nIn some cases you may also want to set the \nrender_style\n attribute to \n'binary'\n. Doing so will also ensure that the browsable API will not attempt to display the binary content as a string.\n\n\nclass JPEGRenderer(renderers.BaseRenderer):\n media_type = 'image/jpeg'\n format = 'jpg'\n charset = None\n render_style = 'binary'\n\n def render(self, data, media_type=None, renderer_context=None):\n return data\n\n\n\n\n\nAdvanced renderer usage\n\n\nYou can do some pretty flexible things using REST framework's renderers. Some examples...\n\n\n\n\nProvide either flat or nested representations from the same endpoint, depending on the requested media type.\n\n\nServe both regular HTML webpages, and JSON based API responses from the same endpoints.\n\n\nSpecify multiple types of HTML representation for API clients to use.\n\n\nUnderspecify a renderer's media type, such as using \nmedia_type = 'image/*'\n, and use the \nAccept\n header to vary the encoding of the response.\n\n\n\n\nVarying behaviour by media type\n\n\nIn some cases you might want your view to use different serialization styles depending on the accepted media type. If you need to do this you can access \nrequest.accepted_renderer\n to determine the negotiated renderer that will be used for the response.\n\n\nFor example:\n\n\n@api_view(('GET',))\n@renderer_classes((TemplateHTMLRenderer, JSONRenderer))\ndef list_users(request):\n \"\"\"\n A view that can return JSON or HTML representations\n of the users in the system.\n \"\"\"\n queryset = Users.objects.filter(active=True)\n\n if request.accepted_renderer.format == 'html':\n # TemplateHTMLRenderer takes a context dict,\n # and additionally requires a 'template_name'.\n # It does not require serialization.\n data = {'users': queryset}\n return Response(data, template_name='list_users.html')\n\n # JSONRenderer requires serialized data as normal.\n serializer = UserSerializer(instance=queryset)\n data = serializer.data\n return Response(data)\n\n\n\nUnderspecifying the media type\n\n\nIn some cases you might want a renderer to serve a range of media types.\nIn this case you can underspecify the media types it should respond to, by using a \nmedia_type\n value such as \nimage/*\n, or \n*/*\n.\n\n\nIf you underspecify the renderer's media type, you should make sure to specify the media type explicitly when you return the response, using the \ncontent_type\n attribute. For example:\n\n\nreturn Response(data, content_type='image/png')\n\n\n\nDesigning your media types\n\n\nFor the purposes of many Web APIs, simple \nJSON\n responses with hyperlinked relations may be sufficient. If you want to fully embrace RESTful design and \nHATEOAS\n you'll need to consider the design and usage of your media types in more detail.\n\n\nIn \nthe words of Roy Fielding\n, \"A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types.\".\n\n\nFor good examples of custom media types, see GitHub's use of a custom \napplication/vnd.github+json\n media type, and Mike Amundsen's IANA approved \napplication/vnd.collection+json\n JSON-based hypermedia.\n\n\nHTML error views\n\n\nTypically a renderer will behave the same regardless of if it's dealing with a regular response, or with a response caused by an exception being raised, such as an \nHttp404\n or \nPermissionDenied\n exception, or a subclass of \nAPIException\n.\n\n\nIf you're using either the \nTemplateHTMLRenderer\n or the \nStaticHTMLRenderer\n and an exception is raised, the behavior is slightly different, and mirrors \nDjango's default handling of error views\n.\n\n\nExceptions raised and handled by an HTML renderer will attempt to render using one of the following methods, by order of precedence.\n\n\n\n\nLoad and render a template named \n{status_code}.html\n.\n\n\nLoad and render a template named \napi_exception.html\n.\n\n\nRender the HTTP status code and text, for example \"404 Not Found\".\n\n\n\n\nTemplates will render with a \nRequestContext\n which includes the \nstatus_code\n and \ndetails\n keys.\n\n\nNote\n: If \nDEBUG=True\n, Django's standard traceback error page will be displayed instead of rendering the HTTP status code and text.\n\n\n\n\nThird party packages\n\n\nThe following third party packages are also available.\n\n\nYAML\n\n\nREST framework YAML\n provides \nYAML\n parsing and rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.\n\n\nInstallation \n configuration\n\n\nInstall using pip.\n\n\n$ pip install djangorestframework-yaml\n\n\n\nModify your REST framework settings.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_PARSER_CLASSES': (\n 'rest_framework_yaml.parsers.YAMLParser',\n ),\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework_yaml.renderers.YAMLRenderer',\n ),\n}\n\n\n\nXML\n\n\nREST Framework XML\n provides a simple informal XML format. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.\n\n\nInstallation \n configuration\n\n\nInstall using pip.\n\n\n$ pip install djangorestframework-xml\n\n\n\nModify your REST framework settings.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_PARSER_CLASSES': (\n 'rest_framework_xml.parsers.XMLParser',\n ),\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework_xml.renderers.XMLRenderer',\n ),\n}\n\n\n\nJSONP\n\n\nREST framework JSONP\n provides JSONP rendering support. It was previously included directly in the REST framework package, and is now instead supported as a third-party package.\n\n\n\n\nWarning\n: If you require cross-domain AJAX requests, you should generally be using the more modern approach of \nCORS\n as an alternative to \nJSONP\n. See the \nCORS documentation\n for more details.\n\n\nThe \njsonp\n approach is essentially a browser hack, and is \nonly appropriate for globally readable API endpoints\n, where \nGET\n requests are unauthenticated and do not require any user permissions.\n\n\n\n\nInstallation \n configuration\n\n\nInstall using pip.\n\n\n$ pip install djangorestframework-jsonp\n\n\n\nModify your REST framework settings.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_RENDERER_CLASSES': (\n 'rest_framework_jsonp.renderers.JSONPRenderer',\n ),\n}\n\n\n\nMessagePack\n\n\nMessagePack\n is a fast, efficient binary serialization format. \nJuan Riaza\n maintains the \ndjangorestframework-msgpack\n package which provides MessagePack renderer and parser support for REST framework.\n\n\nCSV\n\n\nComma-separated values are a plain-text tabular data format, that can be easily imported into spreadsheet applications. \nMjumbe Poe\n maintains the \ndjangorestframework-csv\n package which provides CSV renderer support for REST framework.\n\n\nUltraJSON\n\n\nUltraJSON\n is an optimized C JSON encoder which can give significantly faster JSON rendering. \nJacob Haslehurst\n maintains the \ndrf-ujson-renderer\n package which implements JSON rendering using the UJSON package.\n\n\nCamelCase JSON\n\n\ndjangorestframework-camel-case\n provides camel case JSON renderers and parsers for REST framework. This allows serializers to use Python-style underscored field names, but be exposed in the API as Javascript-style camel case field names. It is maintained by \nVitaly Babiy\n.\n\n\nPandas (CSV, Excel, PNG)\n\n\nDjango REST Pandas\n provides a serializer and renderers that support additional data processing and output via the \nPandas\n DataFrame API. Django REST Pandas includes renderers for Pandas-style CSV files, Excel workbooks (both \n.xls\n and \n.xlsx\n), and a number of \nother formats\n. It is maintained by \nS. Andrew Sheppard\n as part of the \nwq Project\n.\n\n\nLaTeX\n\n\nRest Framework Latex\n provides a renderer that outputs PDFs using Laulatex. It is maintained by \nPebble (S/F Software)\n.", "title": "Renderers" }, { @@ -1177,7 +1177,7 @@ }, { "location": "/api-guide/renderers/#templatehtmlrenderer", - "text": "Renders data to HTML, using Django's standard template rendering.\nUnlike other renderers, the data passed to the Response does not need to be serialized. Also, unlike other renderers, you may want to include a template_name argument when creating the Response . The TemplateHTMLRenderer will create a RequestContext , using the response.data as the context dict, and determine a template name to use to render the context. The template name is determined by (in order of preference): An explicit template_name argument passed to the response. An explicit .template_name attribute set on this class. The return result of calling view.get_template_names() . An example of a view that uses TemplateHTMLRenderer : class UserDetail(generics.RetrieveAPIView):\n \"\"\"\n A view that returns a templated HTML representation of a given user.\n \"\"\"\n queryset = User.objects.all()\n renderer_classes = (TemplateHTMLRenderer,)\n\n def get(self, request, *args, **kwargs):\n self.object = self.get_object()\n return Response({'user': self.object}, template_name='user_detail.html') You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint. If you're building websites that use TemplateHTMLRenderer along with other renderer classes, you should consider listing TemplateHTMLRenderer as the first class in the renderer_classes list, so that it will be prioritised first even for browsers that send poorly formed ACCEPT: headers. .media_type : text/html .format : '.html' .charset : utf-8 See also: StaticHTMLRenderer", + "text": "Renders data to HTML, using Django's standard template rendering.\nUnlike other renderers, the data passed to the Response does not need to be serialized. Also, unlike other renderers, you may want to include a template_name argument when creating the Response . The TemplateHTMLRenderer will create a RequestContext , using the response.data as the context dict, and determine a template name to use to render the context. The template name is determined by (in order of preference): An explicit template_name argument passed to the response. An explicit .template_name attribute set on this class. The return result of calling view.get_template_names() . An example of a view that uses TemplateHTMLRenderer : class UserDetail(generics.RetrieveAPIView):\n \"\"\"\n A view that returns a templated HTML representation of a given user.\n \"\"\"\n queryset = User.objects.all()\n renderer_classes = (TemplateHTMLRenderer,)\n\n def get(self, request, *args, **kwargs):\n self.object = self.get_object()\n return Response({'user': self.object}, template_name='user_detail.html') You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint. If you're building websites that use TemplateHTMLRenderer along with other renderer classes, you should consider listing TemplateHTMLRenderer as the first class in the renderer_classes list, so that it will be prioritised first even for browsers that send poorly formed ACCEPT: headers. See the HTML Forms Topic Page for further examples of TemplateHTMLRenderer usage. .media_type : text/html .format : '.html' .charset : utf-8 See also: StaticHTMLRenderer", "title": "TemplateHTMLRenderer" }, { @@ -1707,7 +1707,7 @@ }, { "location": "/api-guide/fields/", - "text": "Serializer fields\n\n\n\n\nEach field in a Form class is responsible not only for validating data, but also for \"cleaning\" it \n normalizing it to a consistent format.\n\n\n \nDjango documentation\n\n\n\n\nSerializer fields handle converting between primitive values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.\n\n\n\n\nNote:\n The serializer fields are declared in \nfields.py\n, but by convention you should import them using \nfrom rest_framework import serializers\n and refer to fields as \nserializers.\nFieldName\n.\n\n\n\n\nCore arguments\n\n\nEach serializer field class constructor takes at least these arguments. Some Field classes take additional, field-specific arguments, but the following should always be accepted:\n\n\nread_only\n\n\nRead-only fields are included in the API output, but should not be included in the input during create or update operations. Any 'read_only' fields that are incorrectly included in the serializer input will be ignored.\n\n\nSet this to \nTrue\n to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization.\n\n\nDefaults to \nFalse\n\n\nwrite_only\n\n\nSet this to \nTrue\n to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.\n\n\nDefaults to \nFalse\n\n\nrequired\n\n\nNormally an error will be raised if a field is not supplied during deserialization.\nSet to false if this field is not required to be present during deserialization.\n\n\nSetting this to \nFalse\n also allows the object attribute or dictionary key to be omitted from output when serializing the instance. If the key is not present it will simply not be included in the output representation.\n\n\nDefaults to \nTrue\n.\n\n\nallow_null\n\n\nNormally an error will be raised if \nNone\n is passed to a serializer field. Set this keyword argument to \nTrue\n if \nNone\n should be considered a valid value.\n\n\nDefaults to \nFalse\n\n\ndefault\n\n\nIf set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behaviour is to not populate the attribute at all.\n\n\nThe \ndefault\n is not applied during partial update operations. In the partial update case only fields that are provided in the incoming data will have a validated value returned.\n\n\nMay be set to a function or other callable, in which case the value will be evaluated each time it is used. When called, it will receive no arguments. If the callable has a \nset_context\n method, that will be called each time before getting the value with the field instance as only argument. This works the same way as for \nvalidators\n.\n\n\nNote that setting a \ndefault\n value implies that the field is not required. Including both the \ndefault\n and \nrequired\n keyword arguments is invalid and will raise an error.\n\n\nsource\n\n\nThe name of the attribute that will be used to populate the field. May be a method that only takes a \nself\n argument, such as \nURLField(source='get_absolute_url')\n, or may use dotted notation to traverse attributes, such as \nEmailField(source='user.email')\n.\n\n\nThe value \nsource='*'\n has a special meaning, and is used to indicate that the entire object should be passed through to the field. This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation.\n\n\nDefaults to the name of the field.\n\n\nvalidators\n\n\nA list of validator functions which should be applied to the incoming field input, and which either raise a validation error or simply return. Validator functions should typically raise \nserializers.ValidationError\n, but Django's built-in \nValidationError\n is also supported for compatibility with validators defined in the Django codebase or third party Django packages.\n\n\nerror_messages\n\n\nA dictionary of error codes to error messages.\n\n\nlabel\n\n\nA short text string that may be used as the name of the field in HTML form fields or other descriptive elements.\n\n\nhelp_text\n\n\nA text string that may be used as a description of the field in HTML form fields or other descriptive elements.\n\n\ninitial\n\n\nA value that should be used for pre-populating the value of HTML form fields. You may pass a callable to it, just as\nyou may do with any regular Django \nField\n:\n\n\nimport datetime\nfrom rest_framework import serializers\nclass ExampleSerializer(serializers.Serializer):\n day = serializers.DateField(initial=datetime.date.today)\n\n\n\nstyle\n\n\nA dictionary of key-value pairs that can be used to control how renderers should render the field.\n\n\nTwo examples here are \n'input_type'\n and \n'base_template'\n:\n\n\n# Use \ninput type=\"password\"\n for the input.\npassword = serializers.CharField(\n style={'input_type': 'password'}\n)\n\n# Use a radio input instead of a select input.\ncolor_channel = serializers.ChoiceField(\n choices=['red', 'green', 'blue'],\n style={'base_template': 'radio.html'}\n)\n\n\n\nFor more details see the \nHTML \n Forms\n documentation.\n\n\n\n\nBoolean fields\n\n\nBooleanField\n\n\nA boolean representation.\n\n\nWhen using HTML encoded form input be aware that omitting a value will always be treated as setting a field to \nFalse\n, even if it has a \ndefault=True\n option specified. This is because HTML checkbox inputs represent the unchecked state by omitting the value, so REST framework treats omission as if it is an empty checkbox input.\n\n\nCorresponds to \ndjango.db.models.fields.BooleanField\n.\n\n\nSignature:\n \nBooleanField()\n\n\nNullBooleanField\n\n\nA boolean representation that also accepts \nNone\n as a valid value.\n\n\nCorresponds to \ndjango.db.models.fields.NullBooleanField\n.\n\n\nSignature:\n \nNullBooleanField()\n\n\n\n\nString fields\n\n\nCharField\n\n\nA text representation. Optionally validates the text to be shorter than \nmax_length\n and longer than \nmin_length\n.\n\n\nCorresponds to \ndjango.db.models.fields.CharField\n or \ndjango.db.models.fields.TextField\n.\n\n\nSignature:\n \nCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)\n\n\n\n\nmax_length\n - Validates that the input contains no more than this number of characters.\n\n\nmin_length\n - Validates that the input contains no fewer than this number of characters.\n\n\nallow_blank\n - If set to \nTrue\n then the empty string should be considered a valid value. If set to \nFalse\n then the empty string is considered invalid and will raise a validation error. Defaults to \nFalse\n.\n\n\ntrim_whitespace\n - If set to \nTrue\n then leading and trailing whitespace is trimmed. Defaults to \nTrue\n.\n\n\n\n\nThe \nallow_null\n option is also available for string fields, although its usage is discouraged in favor of \nallow_blank\n. It is valid to set both \nallow_blank=True\n and \nallow_null=True\n, but doing so means that there will be two differing types of empty value permissible for string representations, which can lead to data inconsistencies and subtle application bugs.\n\n\nEmailField\n\n\nA text representation, validates the text to be a valid e-mail address.\n\n\nCorresponds to \ndjango.db.models.fields.EmailField\n\n\nSignature:\n \nEmailField(max_length=None, min_length=None, allow_blank=False)\n\n\nRegexField\n\n\nA text representation, that validates the given value matches against a certain regular expression.\n\n\nCorresponds to \ndjango.forms.fields.RegexField\n.\n\n\nSignature:\n \nRegexField(regex, max_length=None, min_length=None, allow_blank=False)\n\n\nThe mandatory \nregex\n argument may either be a string, or a compiled python regular expression object.\n\n\nUses Django's \ndjango.core.validators.RegexValidator\n for validation.\n\n\nSlugField\n\n\nA \nRegexField\n that validates the input against the pattern \n[a-zA-Z0-9_-]+\n.\n\n\nCorresponds to \ndjango.db.models.fields.SlugField\n.\n\n\nSignature:\n \nSlugField(max_length=50, min_length=None, allow_blank=False)\n\n\nURLField\n\n\nA \nRegexField\n that validates the input against a URL matching pattern. Expects fully qualified URLs of the form \nhttp://\nhost\n/\npath\n.\n\n\nCorresponds to \ndjango.db.models.fields.URLField\n. Uses Django's \ndjango.core.validators.URLValidator\n for validation.\n\n\nSignature:\n \nURLField(max_length=200, min_length=None, allow_blank=False)\n\n\nUUIDField\n\n\nA field that ensures the input is a valid UUID string. The \nto_internal_value\n method will return a \nuuid.UUID\n instance. On output the field will return a string in the canonical hyphenated format, for example:\n\n\n\"de305d54-75b4-431b-adb2-eb6b9e546013\"\n\n\n\nSignature:\n \nUUIDField(format='hex_verbose')\n\n\n\n\nformat\n: Determines the representation format of the uuid value\n\n\n'hex_verbose'\n - The cannoncical hex representation, including hyphens: \n\"5ce0e9a5-5ffa-654b-cee0-1238041fb31a\"\n\n\n'hex'\n - The compact hex representation of the UUID, not including hyphens: \n\"5ce0e9a55ffa654bcee01238041fb31a\"\n\n\n'int'\n - A 128 bit integer representation of the UUID: \n\"123456789012312313134124512351145145114\"\n\n\n'urn'\n - RFC 4122 URN representation of the UUID: \n\"urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a\"\n\n Changing the \nformat\n parameters only affects representation values. All formats are accepted by \nto_internal_value\n\n\n\n\n\n\n\n\nFilePathField\n\n\nA field whose choices are limited to the filenames in a certain directory on the filesystem\n\n\nCorresponds to \ndjango.forms.fields.FilePathField\n.\n\n\nSignature:\n \nFilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)\n\n\n\n\npath\n - The absolute filesystem path to a directory from which this FilePathField should get its choice.\n\n\nmatch\n - A regular expression, as a string, that FilePathField will use to filter filenames.\n\n\nrecursive\n - Specifies whether all subdirectories of path should be included. Default is \nFalse\n.\n\n\nallow_files\n - Specifies whether files in the specified location should be included. Default is \nTrue\n. Either this or \nallow_folders\n must be \nTrue\n.\n\n\nallow_folders\n - Specifies whether folders in the specified location should be included. Default is \nFalse\n. Either this or \nallow_files\n must be \nTrue\n.\n\n\n\n\nIPAddressField\n\n\nA field that ensures the input is a valid IPv4 or IPv6 string.\n\n\nCorresponds to \ndjango.forms.fields.IPAddressField\n and \ndjango.forms.fields.GenericIPAddressField\n.\n\n\nSignature\n: \nIPAddressField(protocol='both', unpack_ipv4=False, **options)\n\n\n\n\nprotocol\n Limits valid inputs to the specified protocol. Accepted values are 'both' (default), 'IPv4' or 'IPv6'. Matching is case insensitive.\n\n\nunpack_ipv4\n Unpacks IPv4 mapped addresses like ::ffff:192.0.2.1. If this option is enabled that address would be unpacked to 192.0.2.1. Default is disabled. Can only be used when protocol is set to 'both'.\n\n\n\n\n\n\nNumeric fields\n\n\nIntegerField\n\n\nAn integer representation.\n\n\nCorresponds to \ndjango.db.models.fields.IntegerField\n, \ndjango.db.models.fields.SmallIntegerField\n, \ndjango.db.models.fields.PositiveIntegerField\n and \ndjango.db.models.fields.PositiveSmallIntegerField\n.\n\n\nSignature\n: \nIntegerField(max_value=None, min_value=None)\n\n\n\n\nmax_value\n Validate that the number provided is no greater than this value.\n\n\nmin_value\n Validate that the number provided is no less than this value.\n\n\n\n\nFloatField\n\n\nA floating point representation.\n\n\nCorresponds to \ndjango.db.models.fields.FloatField\n.\n\n\nSignature\n: \nFloatField(max_value=None, min_value=None)\n\n\n\n\nmax_value\n Validate that the number provided is no greater than this value.\n\n\nmin_value\n Validate that the number provided is no less than this value.\n\n\n\n\nDecimalField\n\n\nA decimal representation, represented in Python by a \nDecimal\n instance.\n\n\nCorresponds to \ndjango.db.models.fields.DecimalField\n.\n\n\nSignature\n: \nDecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)\n\n\n\n\nmax_digits\n The maximum number of digits allowed in the number. Note that this number must be greater than or equal to decimal_places.\n\n\ndecimal_places\n The number of decimal places to store with the number.\n\n\ncoerce_to_string\n Set to \nTrue\n if string values should be returned for the representation, or \nFalse\n if \nDecimal\n objects should be returned. Defaults to the same value as the \nCOERCE_DECIMAL_TO_STRING\n settings key, which will be \nTrue\n unless overridden. If \nDecimal\n objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting \nlocalize\n will force the value to \nTrue\n.\n\n\nmax_value\n Validate that the number provided is no greater than this value.\n\n\nmin_value\n Validate that the number provided is no less than this value.\n\n\nlocalize\n Set to \nTrue\n to enable localization of input and output based on the current locale. This will also force \ncoerce_to_string\n to \nTrue\n. Defaults to \nFalse\n. Note that data formatting is enabled if you have set \nUSE_L10N=True\n in your settings file.\n\n\n\n\nExample usage\n\n\nTo validate numbers up to 999 with a resolution of 2 decimal places, you would use:\n\n\nserializers.DecimalField(max_digits=5, decimal_places=2)\n\n\n\nAnd to validate numbers up to anything less than one billion with a resolution of 10 decimal places:\n\n\nserializers.DecimalField(max_digits=19, decimal_places=10)\n\n\n\nThis field also takes an optional argument, \ncoerce_to_string\n. If set to \nTrue\n the representation will be output as a string. If set to \nFalse\n the representation will be left as a \nDecimal\n instance and the final representation will be determined by the renderer.\n\n\nIf unset, this will default to the same value as the \nCOERCE_DECIMAL_TO_STRING\n setting, which is \nTrue\n unless set otherwise.\n\n\n\n\nDate and time fields\n\n\nDateTimeField\n\n\nA date and time representation.\n\n\nCorresponds to \ndjango.db.models.fields.DateTimeField\n.\n\n\nSignature:\n \nDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)\n\n\n\n\nformat\n - A string representing the output format. If not specified, this defaults to the same value as the \nDATETIME_FORMAT\n settings key, which will be \n'iso-8601'\n unless set. Setting to a format string indicates that \nto_representation\n return values should be coerced to string output. Format strings are described below. Setting this value to \nNone\n indicates that Python \ndatetime\n objects should be returned by \nto_representation\n. In this case the datetime encoding will be determined by the renderer.\n\n\ninput_formats\n - A list of strings representing the input formats which may be used to parse the date. If not specified, the \nDATETIME_INPUT_FORMATS\n setting will be used, which defaults to \n['iso-8601']\n.\n\n\n\n\nDateTimeField\n format strings.\n\n\nFormat strings may either be \nPython strftime formats\n which explicitly specify the format, or the special string \n'iso-8601'\n, which indicates that \nISO 8601\n style datetimes should be used. (eg \n'2013-01-29T12:34:56.000000Z'\n)\n\n\nWhen a value of \nNone\n is used for the format \ndatetime\n objects will be returned by \nto_representation\n and the final output representation will determined by the renderer class.\n\n\nIn the case of JSON this means the default datetime representation uses the \nECMA 262 date time string specification\n. This is a subset of ISO 8601 which uses millisecond precision, and includes the 'Z' suffix for the UTC timezone, for example: \n2013-01-29T12:34:56.123Z\n.\n\n\nauto_now_add\n model fields.\nauto_now\n and \n\n\nWhen using \nModelSerializer\n or \nHyperlinkedModelSerializer\n, note that any model fields with \nauto_now=True\n or \nauto_now_add=True\n will use serializer fields that are \nread_only=True\n by default.\n\n\nIf you want to override this behavior, you'll need to declare the \nDateTimeField\n explicitly on the serializer. For example:\n\n\nclass CommentSerializer(serializers.ModelSerializer):\n created = serializers.DateTimeField()\n\n class Meta:\n model = Comment\n\n\n\nDateField\n\n\nA date representation.\n\n\nCorresponds to \ndjango.db.models.fields.DateField\n\n\nSignature:\n \nDateField(format=api_settings.DATE_FORMAT, input_formats=None)\n\n\n\n\nformat\n - A string representing the output format. If not specified, this defaults to the same value as the \nDATE_FORMAT\n settings key, which will be \n'iso-8601'\n unless set. Setting to a format string indicates that \nto_representation\n return values should be coerced to string output. Format strings are described below. Setting this value to \nNone\n indicates that Python \ndate\n objects should be returned by \nto_representation\n. In this case the date encoding will be determined by the renderer.\n\n\ninput_formats\n - A list of strings representing the input formats which may be used to parse the date. If not specified, the \nDATE_INPUT_FORMATS\n setting will be used, which defaults to \n['iso-8601']\n.\n\n\n\n\nDateField\n format strings\n\n\nFormat strings may either be \nPython strftime formats\n which explicitly specify the format, or the special string \n'iso-8601'\n, which indicates that \nISO 8601\n style dates should be used. (eg \n'2013-01-29'\n)\n\n\nTimeField\n\n\nA time representation.\n\n\nCorresponds to \ndjango.db.models.fields.TimeField\n\n\nSignature:\n \nTimeField(format=api_settings.TIME_FORMAT, input_formats=None)\n\n\n\n\nformat\n - A string representing the output format. If not specified, this defaults to the same value as the \nTIME_FORMAT\n settings key, which will be \n'iso-8601'\n unless set. Setting to a format string indicates that \nto_representation\n return values should be coerced to string output. Format strings are described below. Setting this value to \nNone\n indicates that Python \ntime\n objects should be returned by \nto_representation\n. In this case the time encoding will be determined by the renderer.\n\n\ninput_formats\n - A list of strings representing the input formats which may be used to parse the date. If not specified, the \nTIME_INPUT_FORMATS\n setting will be used, which defaults to \n['iso-8601']\n.\n\n\n\n\nTimeField\n format strings\n\n\nFormat strings may either be \nPython strftime formats\n which explicitly specify the format, or the special string \n'iso-8601'\n, which indicates that \nISO 8601\n style times should be used. (eg \n'12:34:56.000000'\n)\n\n\nDurationField\n\n\nA Duration representation.\nCorresponds to \ndjango.db.models.fields.DurationField\n\n\nThe \nvalidated_data\n for these fields will contain a \ndatetime.timedelta\n instance.\nThe representation is a string following this format \n'[DD] [HH:[MM:]]ss[.uuuuuu]'\n.\n\n\nNote:\n This field is only available with Django versions \n= 1.8.\n\n\nSignature:\n \nDurationField()\n\n\n\n\nChoice selection fields\n\n\nChoiceField\n\n\nA field that can accept a value out of a limited set of choices.\n\n\nUsed by \nModelSerializer\n to automatically generate fields if the corresponding model field includes a \nchoices=\u2026\n argument.\n\n\nSignature:\n \nChoiceField(choices)\n\n\n\n\nchoices\n - A list of valid values, or a list of \n(key, display_name)\n tuples.\n\n\nallow_blank\n - If set to \nTrue\n then the empty string should be considered a valid value. If set to \nFalse\n then the empty string is considered invalid and will raise a validation error. Defaults to \nFalse\n.\n\n\nhtml_cutoff\n - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Can be used to ensure that automatically generated ChoiceFields with very large possible selections do not prevent a template from rendering. Defaults to \nNone\n.\n\n\nhtml_cutoff_text\n - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to \n\"More than {count} items\u2026\"\n\n\n\n\nBoth the \nallow_blank\n and \nallow_null\n are valid options on \nChoiceField\n, although it is highly recommended that you only use one and not both. \nallow_blank\n should be preferred for textual choices, and \nallow_null\n should be preferred for numeric or other non-textual choices.\n\n\nMultipleChoiceField\n\n\nA field that can accept a set of zero, one or many values, chosen from a limited set of choices. Takes a single mandatory argument. \nto_internal_value\n returns a \nset\n containing the selected values.\n\n\nSignature:\n \nMultipleChoiceField(choices)\n\n\n\n\nchoices\n - A list of valid values, or a list of \n(key, display_name)\n tuples.\n\n\nallow_blank\n - If set to \nTrue\n then the empty string should be considered a valid value. If set to \nFalse\n then the empty string is considered invalid and will raise a validation error. Defaults to \nFalse\n.\n\n\nhtml_cutoff\n - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Can be used to ensure that automatically generated ChoiceFields with very large possible selections do not prevent a template from rendering. Defaults to \nNone\n.\n\n\nhtml_cutoff_text\n - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to \n\"More than {count} items\u2026\"\n\n\n\n\nAs with \nChoiceField\n, both the \nallow_blank\n and \nallow_null\n options are valid, although it is highly recommended that you only use one and not both. \nallow_blank\n should be preferred for textual choices, and \nallow_null\n should be preferred for numeric or other non-textual choices.\n\n\n\n\nFile upload fields\n\n\nParsers and file uploads.\n\n\nThe \nFileField\n and \nImageField\n classes are only suitable for use with \nMultiPartParser\n or \nFileUploadParser\n. Most parsers, such as e.g. JSON don't support file uploads.\nDjango's regular \nFILE_UPLOAD_HANDLERS\n are used for handling uploaded files.\n\n\nFileField\n\n\nA file representation. Performs Django's standard FileField validation.\n\n\nCorresponds to \ndjango.forms.fields.FileField\n.\n\n\nSignature:\n \nFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)\n\n\n\n\nmax_length\n - Designates the maximum length for the file name.\n\n\nallow_empty_file\n - Designates if empty files are allowed.\n\n\nuse_url\n - If set to \nTrue\n then URL string values will be used for the output representation. If set to \nFalse\n then filename string values will be used for the output representation. Defaults to the value of the \nUPLOADED_FILES_USE_URL\n settings key, which is \nTrue\n unless set otherwise.\n\n\n\n\nImageField\n\n\nAn image representation. Validates the uploaded file content as matching a known image format.\n\n\nCorresponds to \ndjango.forms.fields.ImageField\n.\n\n\nSignature:\n \nImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)\n\n\n\n\nmax_length\n - Designates the maximum length for the file name.\n\n\nallow_empty_file\n - Designates if empty files are allowed.\n\n\nuse_url\n - If set to \nTrue\n then URL string values will be used for the output representation. If set to \nFalse\n then filename string values will be used for the output representation. Defaults to the value of the \nUPLOADED_FILES_USE_URL\n settings key, which is \nTrue\n unless set otherwise.\n\n\n\n\nRequires either the \nPillow\n package or \nPIL\n package. The \nPillow\n package is recommended, as \nPIL\n is no longer actively maintained.\n\n\n\n\nComposite fields\n\n\nListField\n\n\nA field class that validates a list of objects.\n\n\nSignature\n: \nListField(child)\n\n\n\n\nchild\n - A field instance that should be used for validating the objects in the list. If this argument is not provided then objects in the list will not be validated.\n\n\n\n\nFor example, to validate a list of integers you might use something like the following:\n\n\nscores = serializers.ListField(\n child=serializers.IntegerField(min_value=0, max_value=100)\n)\n\n\n\nThe \nListField\n class also supports a declarative style that allows you to write reusable list field classes.\n\n\nclass StringListField(serializers.ListField):\n child = serializers.CharField()\n\n\n\nWe can now reuse our custom \nStringListField\n class throughout our application, without having to provide a \nchild\n argument to it.\n\n\nDictField\n\n\nA field class that validates a dictionary of objects. The keys in \nDictField\n are always assumed to be string values.\n\n\nSignature\n: \nDictField(child)\n\n\n\n\nchild\n - A field instance that should be used for validating the values in the dictionary. If this argument is not provided then values in the mapping will not be validated.\n\n\n\n\nFor example, to create a field that validates a mapping of strings to strings, you would write something like this:\n\n\ndocument = DictField(child=CharField())\n\n\n\nYou can also use the declarative style, as with \nListField\n. For example:\n\n\nclass DocumentField(DictField):\n child = CharField()\n\n\n\nJSONField\n\n\nA field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON-encoded binary strings.\n\n\nSignature\n: \nJSONField(binary)\n\n\n\n\nbinary\n - If set to \nTrue\n then the field will output and validate a JSON encoded string, rather than a primitive data structure. Defaults to \nFalse\n.\n\n\n\n\n\n\nMiscellaneous fields\n\n\nReadOnlyField\n\n\nA field class that simply returns the value of the field without modification.\n\n\nThis field is used by default with \nModelSerializer\n when including field names that relate to an attribute rather than a model field.\n\n\nSignature\n: \nReadOnlyField()\n\n\nFor example, if \nhas_expired\n was a property on the \nAccount\n model, then the following serializer would automatically generate it as a \nReadOnlyField\n:\n\n\nclass AccountSerializer(serializers.ModelSerializer):\n class Meta:\n model = Account\n fields = ('id', 'account_name', 'has_expired')\n\n\n\nHiddenField\n\n\nA field class that does not take a value based on user input, but instead takes its value from a default value or callable.\n\n\nSignature\n: \nHiddenField()\n\n\nFor example, to include a field that always provides the current time as part of the serializer validated data, you would use the following:\n\n\nmodified = serializers.HiddenField(default=timezone.now)\n\n\n\nThe \nHiddenField\n class is usually only needed if you have some validation that needs to run based on some pre-provided field values, but you do not want to expose all of those fields to the end user.\n\n\nFor further examples on \nHiddenField\n see the \nvalidators\n documentation.\n\n\nModelField\n\n\nA generic field that can be tied to any arbitrary model field. The \nModelField\n class delegates the task of serialization/deserialization to its associated model field. This field can be used to create serializer fields for custom model fields, without having to create a new custom serializer field.\n\n\nThis field is used by \nModelSerializer\n to correspond to custom model field classes.\n\n\nSignature:\n \nModelField(model_field=\nDjango ModelField instance\n)\n\n\nThe \nModelField\n class is generally intended for internal use, but can be used by your API if needed. In order to properly instantiate a \nModelField\n, it must be passed a field that is attached to an instantiated model. For example: \nModelField(model_field=MyModel()._meta.get_field('custom_field'))\n\n\nSerializerMethodField\n\n\nThis is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.\n\n\nSignature\n: \nSerializerMethodField(method_name=None)\n\n\n\n\nmethod_name\n - The name of the method on the serializer to be called. If not included this defaults to \nget_\nfield_name\n.\n\n\n\n\nThe serializer method referred to by the \nmethod_name\n argument should accept a single argument (in addition to \nself\n), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:\n\n\nfrom django.contrib.auth.models import User\nfrom django.utils.timezone import now\nfrom rest_framework import serializers\n\nclass UserSerializer(serializers.ModelSerializer):\n days_since_joined = serializers.SerializerMethodField()\n\n class Meta:\n model = User\n\n def get_days_since_joined(self, obj):\n return (now() - obj.date_joined).days\n\n\n\n\n\nCustom fields\n\n\nIf you want to create a custom field, you'll need to subclass \nField\n and then override either one or both of the \n.to_representation()\n and \n.to_internal_value()\n methods. These two methods are used to convert between the initial datatype, and a primitive, serializable datatype. Primitive datatypes will typically be any of a number, string, boolean, \ndate\n/\ntime\n/\ndatetime\n or \nNone\n. They may also be any list or dictionary like object that only contains other primitive objects. Other types might be supported, depending on the renderer that you are using.\n\n\nThe \n.to_representation()\n method is called to convert the initial datatype into a primitive, serializable datatype.\n\n\nThe \nto_internal_value()\n method is called to restore a primitive datatype into its internal python representation. This method should raise a \nserializers.ValidationError\n if the data is invalid.\n\n\nNote that the \nWritableField\n class that was present in version 2.x no longer exists. You should subclass \nField\n and override \nto_internal_value()\n if the field supports data input.\n\n\nExamples\n\n\nLet's look at an example of serializing a class that represents an RGB color value:\n\n\nclass Color(object):\n \"\"\"\n A color represented in the RGB colorspace.\n \"\"\"\n def __init__(self, red, green, blue):\n assert(red \n= 0 and green \n= 0 and blue \n= 0)\n assert(red \n 256 and green \n 256 and blue \n 256)\n self.red, self.green, self.blue = red, green, blue\n\nclass ColorField(serializers.Field):\n \"\"\"\n Color objects are serialized into 'rgb(#, #, #)' notation.\n \"\"\"\n def to_representation(self, obj):\n return \"rgb(%d, %d, %d)\" % (obj.red, obj.green, obj.blue)\n\n def to_internal_value(self, data):\n data = data.strip('rgb(').rstrip(')')\n red, green, blue = [int(col) for col in data.split(',')]\n return Color(red, green, blue)\n\n\n\nBy default field values are treated as mapping to an attribute on the object. If you need to customize how the field value is accessed and set you need to override \n.get_attribute()\n and/or \n.get_value()\n.\n\n\nAs an example, let's create a field that can be used to represent the class name of the object being serialized:\n\n\nclass ClassNameField(serializers.Field):\n def get_attribute(self, obj):\n # We pass the object instance onto `to_representation`,\n # not just the field attribute.\n return obj\n\n def to_representation(self, obj):\n \"\"\"\n Serialize the object's class name.\n \"\"\"\n return obj.__class__.__name__\n\n\n\nRaising validation errors\n\n\nOur \nColorField\n class above currently does not perform any data validation.\nTo indicate invalid data, we should raise a \nserializers.ValidationError\n, like so:\n\n\ndef to_internal_value(self, data):\n if not isinstance(data, six.text_type):\n msg = 'Incorrect type. Expected a string, but got %s'\n raise ValidationError(msg % type(data).__name__)\n\n if not re.match(r'^rgb\\([0-9]+,[0-9]+,[0-9]+\\)$', data):\n raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')\n\n data = data.strip('rgb(').rstrip(')')\n red, green, blue = [int(col) for col in data.split(',')]\n\n if any([col \n 255 or col \n 0 for col in (red, green, blue)]):\n raise ValidationError('Value out of range. Must be between 0 and 255.')\n\n return Color(red, green, blue)\n\n\n\nThe \n.fail()\n method is a shortcut for raising \nValidationError\n that takes a message string from the \nerror_messages\n dictionary. For example:\n\n\ndefault_error_messages = {\n 'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',\n 'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',\n 'out_of_range': 'Value out of range. Must be between 0 and 255.'\n}\n\ndef to_internal_value(self, data):\n if not isinstance(data, six.text_type):\n self.fail('incorrect_type', input_type=type(data).__name__)\n\n if not re.match(r'^rgb\\([0-9]+,[0-9]+,[0-9]+\\)$', data):\n self.fail('incorrect_format')\n\n data = data.strip('rgb(').rstrip(')')\n red, green, blue = [int(col) for col in data.split(',')]\n\n if any([col \n 255 or col \n 0 for col in (red, green, blue)]):\n self.fail('out_of_range')\n\n return Color(red, green, blue)\n\n\n\nThis style keeps you error messages more cleanly separated from your code, and should be preferred.\n\n\nThird party packages\n\n\nThe following third party packages are also available.\n\n\nDRF Compound Fields\n\n\nThe \ndrf-compound-fields\n package provides \"compound\" serializer fields, such as lists of simple values, which can be described by other fields rather than serializers with the \nmany=True\n option. Also provided are fields for typed dictionaries and values that can be either a specific type or a list of items of that type.\n\n\nDRF Extra Fields\n\n\nThe \ndrf-extra-fields\n package provides extra serializer fields for REST framework, including \nBase64ImageField\n and \nPointField\n classes.\n\n\ndjangrestframework-recursive\n\n\nthe \ndjangorestframework-recursive\n package provides a \nRecursiveField\n for serializing and deserializing recursive structures\n\n\ndjango-rest-framework-gis\n\n\nThe \ndjango-rest-framework-gis\n package provides geographic addons for django rest framework like a \nGeometryField\n field and a GeoJSON serializer.\n\n\ndjango-rest-framework-hstore\n\n\nThe \ndjango-rest-framework-hstore\n package provides an \nHStoreField\n to support \ndjango-hstore\n \nDictionaryField\n model field.", + "text": "Serializer fields\n\n\n\n\nEach field in a Form class is responsible not only for validating data, but also for \"cleaning\" it \n normalizing it to a consistent format.\n\n\n \nDjango documentation\n\n\n\n\nSerializer fields handle converting between primitive values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.\n\n\n\n\nNote:\n The serializer fields are declared in \nfields.py\n, but by convention you should import them using \nfrom rest_framework import serializers\n and refer to fields as \nserializers.\nFieldName\n.\n\n\n\n\nCore arguments\n\n\nEach serializer field class constructor takes at least these arguments. Some Field classes take additional, field-specific arguments, but the following should always be accepted:\n\n\nread_only\n\n\nRead-only fields are included in the API output, but should not be included in the input during create or update operations. Any 'read_only' fields that are incorrectly included in the serializer input will be ignored.\n\n\nSet this to \nTrue\n to ensure that the field is used when serializing a representation, but is not used when creating or updating an instance during deserialization.\n\n\nDefaults to \nFalse\n\n\nwrite_only\n\n\nSet this to \nTrue\n to ensure that the field may be used when updating or creating an instance, but is not included when serializing the representation.\n\n\nDefaults to \nFalse\n\n\nrequired\n\n\nNormally an error will be raised if a field is not supplied during deserialization.\nSet to false if this field is not required to be present during deserialization.\n\n\nSetting this to \nFalse\n also allows the object attribute or dictionary key to be omitted from output when serializing the instance. If the key is not present it will simply not be included in the output representation.\n\n\nDefaults to \nTrue\n.\n\n\nallow_null\n\n\nNormally an error will be raised if \nNone\n is passed to a serializer field. Set this keyword argument to \nTrue\n if \nNone\n should be considered a valid value.\n\n\nDefaults to \nFalse\n\n\ndefault\n\n\nIf set, this gives the default value that will be used for the field if no input value is supplied. If not set the default behaviour is to not populate the attribute at all.\n\n\nThe \ndefault\n is not applied during partial update operations. In the partial update case only fields that are provided in the incoming data will have a validated value returned.\n\n\nMay be set to a function or other callable, in which case the value will be evaluated each time it is used. When called, it will receive no arguments. If the callable has a \nset_context\n method, that will be called each time before getting the value with the field instance as only argument. This works the same way as for \nvalidators\n.\n\n\nNote that setting a \ndefault\n value implies that the field is not required. Including both the \ndefault\n and \nrequired\n keyword arguments is invalid and will raise an error.\n\n\nsource\n\n\nThe name of the attribute that will be used to populate the field. May be a method that only takes a \nself\n argument, such as \nURLField(source='get_absolute_url')\n, or may use dotted notation to traverse attributes, such as \nEmailField(source='user.email')\n.\n\n\nThe value \nsource='*'\n has a special meaning, and is used to indicate that the entire object should be passed through to the field. This can be useful for creating nested representations, or for fields which require access to the complete object in order to determine the output representation.\n\n\nDefaults to the name of the field.\n\n\nvalidators\n\n\nA list of validator functions which should be applied to the incoming field input, and which either raise a validation error or simply return. Validator functions should typically raise \nserializers.ValidationError\n, but Django's built-in \nValidationError\n is also supported for compatibility with validators defined in the Django codebase or third party Django packages.\n\n\nerror_messages\n\n\nA dictionary of error codes to error messages.\n\n\nlabel\n\n\nA short text string that may be used as the name of the field in HTML form fields or other descriptive elements.\n\n\nhelp_text\n\n\nA text string that may be used as a description of the field in HTML form fields or other descriptive elements.\n\n\ninitial\n\n\nA value that should be used for pre-populating the value of HTML form fields. You may pass a callable to it, just as\nyou may do with any regular Django \nField\n:\n\n\nimport datetime\nfrom rest_framework import serializers\nclass ExampleSerializer(serializers.Serializer):\n day = serializers.DateField(initial=datetime.date.today)\n\n\n\nstyle\n\n\nA dictionary of key-value pairs that can be used to control how renderers should render the field.\n\n\nTwo examples here are \n'input_type'\n and \n'base_template'\n:\n\n\n# Use \ninput type=\"password\"\n for the input.\npassword = serializers.CharField(\n style={'input_type': 'password'}\n)\n\n# Use a radio input instead of a select input.\ncolor_channel = serializers.ChoiceField(\n choices=['red', 'green', 'blue'],\n style={'base_template': 'radio.html'}\n)\n\n\n\nFor more details see the \nHTML \n Forms\n documentation.\n\n\n\n\nBoolean fields\n\n\nBooleanField\n\n\nA boolean representation.\n\n\nWhen using HTML encoded form input be aware that omitting a value will always be treated as setting a field to \nFalse\n, even if it has a \ndefault=True\n option specified. This is because HTML checkbox inputs represent the unchecked state by omitting the value, so REST framework treats omission as if it is an empty checkbox input.\n\n\nCorresponds to \ndjango.db.models.fields.BooleanField\n.\n\n\nSignature:\n \nBooleanField()\n\n\nNullBooleanField\n\n\nA boolean representation that also accepts \nNone\n as a valid value.\n\n\nCorresponds to \ndjango.db.models.fields.NullBooleanField\n.\n\n\nSignature:\n \nNullBooleanField()\n\n\n\n\nString fields\n\n\nCharField\n\n\nA text representation. Optionally validates the text to be shorter than \nmax_length\n and longer than \nmin_length\n.\n\n\nCorresponds to \ndjango.db.models.fields.CharField\n or \ndjango.db.models.fields.TextField\n.\n\n\nSignature:\n \nCharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)\n\n\n\n\nmax_length\n - Validates that the input contains no more than this number of characters.\n\n\nmin_length\n - Validates that the input contains no fewer than this number of characters.\n\n\nallow_blank\n - If set to \nTrue\n then the empty string should be considered a valid value. If set to \nFalse\n then the empty string is considered invalid and will raise a validation error. Defaults to \nFalse\n.\n\n\ntrim_whitespace\n - If set to \nTrue\n then leading and trailing whitespace is trimmed. Defaults to \nTrue\n.\n\n\n\n\nThe \nallow_null\n option is also available for string fields, although its usage is discouraged in favor of \nallow_blank\n. It is valid to set both \nallow_blank=True\n and \nallow_null=True\n, but doing so means that there will be two differing types of empty value permissible for string representations, which can lead to data inconsistencies and subtle application bugs.\n\n\nEmailField\n\n\nA text representation, validates the text to be a valid e-mail address.\n\n\nCorresponds to \ndjango.db.models.fields.EmailField\n\n\nSignature:\n \nEmailField(max_length=None, min_length=None, allow_blank=False)\n\n\nRegexField\n\n\nA text representation, that validates the given value matches against a certain regular expression.\n\n\nCorresponds to \ndjango.forms.fields.RegexField\n.\n\n\nSignature:\n \nRegexField(regex, max_length=None, min_length=None, allow_blank=False)\n\n\nThe mandatory \nregex\n argument may either be a string, or a compiled python regular expression object.\n\n\nUses Django's \ndjango.core.validators.RegexValidator\n for validation.\n\n\nSlugField\n\n\nA \nRegexField\n that validates the input against the pattern \n[a-zA-Z0-9_-]+\n.\n\n\nCorresponds to \ndjango.db.models.fields.SlugField\n.\n\n\nSignature:\n \nSlugField(max_length=50, min_length=None, allow_blank=False)\n\n\nURLField\n\n\nA \nRegexField\n that validates the input against a URL matching pattern. Expects fully qualified URLs of the form \nhttp://\nhost\n/\npath\n.\n\n\nCorresponds to \ndjango.db.models.fields.URLField\n. Uses Django's \ndjango.core.validators.URLValidator\n for validation.\n\n\nSignature:\n \nURLField(max_length=200, min_length=None, allow_blank=False)\n\n\nUUIDField\n\n\nA field that ensures the input is a valid UUID string. The \nto_internal_value\n method will return a \nuuid.UUID\n instance. On output the field will return a string in the canonical hyphenated format, for example:\n\n\n\"de305d54-75b4-431b-adb2-eb6b9e546013\"\n\n\n\nSignature:\n \nUUIDField(format='hex_verbose')\n\n\n\n\nformat\n: Determines the representation format of the uuid value\n\n\n'hex_verbose'\n - The cannoncical hex representation, including hyphens: \n\"5ce0e9a5-5ffa-654b-cee0-1238041fb31a\"\n\n\n'hex'\n - The compact hex representation of the UUID, not including hyphens: \n\"5ce0e9a55ffa654bcee01238041fb31a\"\n\n\n'int'\n - A 128 bit integer representation of the UUID: \n\"123456789012312313134124512351145145114\"\n\n\n'urn'\n - RFC 4122 URN representation of the UUID: \n\"urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a\"\n\n Changing the \nformat\n parameters only affects representation values. All formats are accepted by \nto_internal_value\n\n\n\n\n\n\n\n\nFilePathField\n\n\nA field whose choices are limited to the filenames in a certain directory on the filesystem\n\n\nCorresponds to \ndjango.forms.fields.FilePathField\n.\n\n\nSignature:\n \nFilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)\n\n\n\n\npath\n - The absolute filesystem path to a directory from which this FilePathField should get its choice.\n\n\nmatch\n - A regular expression, as a string, that FilePathField will use to filter filenames.\n\n\nrecursive\n - Specifies whether all subdirectories of path should be included. Default is \nFalse\n.\n\n\nallow_files\n - Specifies whether files in the specified location should be included. Default is \nTrue\n. Either this or \nallow_folders\n must be \nTrue\n.\n\n\nallow_folders\n - Specifies whether folders in the specified location should be included. Default is \nFalse\n. Either this or \nallow_files\n must be \nTrue\n.\n\n\n\n\nIPAddressField\n\n\nA field that ensures the input is a valid IPv4 or IPv6 string.\n\n\nCorresponds to \ndjango.forms.fields.IPAddressField\n and \ndjango.forms.fields.GenericIPAddressField\n.\n\n\nSignature\n: \nIPAddressField(protocol='both', unpack_ipv4=False, **options)\n\n\n\n\nprotocol\n Limits valid inputs to the specified protocol. Accepted values are 'both' (default), 'IPv4' or 'IPv6'. Matching is case insensitive.\n\n\nunpack_ipv4\n Unpacks IPv4 mapped addresses like ::ffff:192.0.2.1. If this option is enabled that address would be unpacked to 192.0.2.1. Default is disabled. Can only be used when protocol is set to 'both'.\n\n\n\n\n\n\nNumeric fields\n\n\nIntegerField\n\n\nAn integer representation.\n\n\nCorresponds to \ndjango.db.models.fields.IntegerField\n, \ndjango.db.models.fields.SmallIntegerField\n, \ndjango.db.models.fields.PositiveIntegerField\n and \ndjango.db.models.fields.PositiveSmallIntegerField\n.\n\n\nSignature\n: \nIntegerField(max_value=None, min_value=None)\n\n\n\n\nmax_value\n Validate that the number provided is no greater than this value.\n\n\nmin_value\n Validate that the number provided is no less than this value.\n\n\n\n\nFloatField\n\n\nA floating point representation.\n\n\nCorresponds to \ndjango.db.models.fields.FloatField\n.\n\n\nSignature\n: \nFloatField(max_value=None, min_value=None)\n\n\n\n\nmax_value\n Validate that the number provided is no greater than this value.\n\n\nmin_value\n Validate that the number provided is no less than this value.\n\n\n\n\nDecimalField\n\n\nA decimal representation, represented in Python by a \nDecimal\n instance.\n\n\nCorresponds to \ndjango.db.models.fields.DecimalField\n.\n\n\nSignature\n: \nDecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)\n\n\n\n\nmax_digits\n The maximum number of digits allowed in the number. It must be either \nNone\n or an integer greater than or equal to \ndecimal_places\n.\n\n\ndecimal_places\n The number of decimal places to store with the number.\n\n\ncoerce_to_string\n Set to \nTrue\n if string values should be returned for the representation, or \nFalse\n if \nDecimal\n objects should be returned. Defaults to the same value as the \nCOERCE_DECIMAL_TO_STRING\n settings key, which will be \nTrue\n unless overridden. If \nDecimal\n objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting \nlocalize\n will force the value to \nTrue\n.\n\n\nmax_value\n Validate that the number provided is no greater than this value.\n\n\nmin_value\n Validate that the number provided is no less than this value.\n\n\nlocalize\n Set to \nTrue\n to enable localization of input and output based on the current locale. This will also force \ncoerce_to_string\n to \nTrue\n. Defaults to \nFalse\n. Note that data formatting is enabled if you have set \nUSE_L10N=True\n in your settings file.\n\n\n\n\nExample usage\n\n\nTo validate numbers up to 999 with a resolution of 2 decimal places, you would use:\n\n\nserializers.DecimalField(max_digits=5, decimal_places=2)\n\n\n\nAnd to validate numbers up to anything less than one billion with a resolution of 10 decimal places:\n\n\nserializers.DecimalField(max_digits=19, decimal_places=10)\n\n\n\nThis field also takes an optional argument, \ncoerce_to_string\n. If set to \nTrue\n the representation will be output as a string. If set to \nFalse\n the representation will be left as a \nDecimal\n instance and the final representation will be determined by the renderer.\n\n\nIf unset, this will default to the same value as the \nCOERCE_DECIMAL_TO_STRING\n setting, which is \nTrue\n unless set otherwise.\n\n\n\n\nDate and time fields\n\n\nDateTimeField\n\n\nA date and time representation.\n\n\nCorresponds to \ndjango.db.models.fields.DateTimeField\n.\n\n\nSignature:\n \nDateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)\n\n\n\n\nformat\n - A string representing the output format. If not specified, this defaults to the same value as the \nDATETIME_FORMAT\n settings key, which will be \n'iso-8601'\n unless set. Setting to a format string indicates that \nto_representation\n return values should be coerced to string output. Format strings are described below. Setting this value to \nNone\n indicates that Python \ndatetime\n objects should be returned by \nto_representation\n. In this case the datetime encoding will be determined by the renderer.\n\n\ninput_formats\n - A list of strings representing the input formats which may be used to parse the date. If not specified, the \nDATETIME_INPUT_FORMATS\n setting will be used, which defaults to \n['iso-8601']\n.\n\n\n\n\nDateTimeField\n format strings.\n\n\nFormat strings may either be \nPython strftime formats\n which explicitly specify the format, or the special string \n'iso-8601'\n, which indicates that \nISO 8601\n style datetimes should be used. (eg \n'2013-01-29T12:34:56.000000Z'\n)\n\n\nWhen a value of \nNone\n is used for the format \ndatetime\n objects will be returned by \nto_representation\n and the final output representation will determined by the renderer class.\n\n\nIn the case of JSON this means the default datetime representation uses the \nECMA 262 date time string specification\n. This is a subset of ISO 8601 which uses millisecond precision, and includes the 'Z' suffix for the UTC timezone, for example: \n2013-01-29T12:34:56.123Z\n.\n\n\nauto_now_add\n model fields.\nauto_now\n and \n\n\nWhen using \nModelSerializer\n or \nHyperlinkedModelSerializer\n, note that any model fields with \nauto_now=True\n or \nauto_now_add=True\n will use serializer fields that are \nread_only=True\n by default.\n\n\nIf you want to override this behavior, you'll need to declare the \nDateTimeField\n explicitly on the serializer. For example:\n\n\nclass CommentSerializer(serializers.ModelSerializer):\n created = serializers.DateTimeField()\n\n class Meta:\n model = Comment\n\n\n\nDateField\n\n\nA date representation.\n\n\nCorresponds to \ndjango.db.models.fields.DateField\n\n\nSignature:\n \nDateField(format=api_settings.DATE_FORMAT, input_formats=None)\n\n\n\n\nformat\n - A string representing the output format. If not specified, this defaults to the same value as the \nDATE_FORMAT\n settings key, which will be \n'iso-8601'\n unless set. Setting to a format string indicates that \nto_representation\n return values should be coerced to string output. Format strings are described below. Setting this value to \nNone\n indicates that Python \ndate\n objects should be returned by \nto_representation\n. In this case the date encoding will be determined by the renderer.\n\n\ninput_formats\n - A list of strings representing the input formats which may be used to parse the date. If not specified, the \nDATE_INPUT_FORMATS\n setting will be used, which defaults to \n['iso-8601']\n.\n\n\n\n\nDateField\n format strings\n\n\nFormat strings may either be \nPython strftime formats\n which explicitly specify the format, or the special string \n'iso-8601'\n, which indicates that \nISO 8601\n style dates should be used. (eg \n'2013-01-29'\n)\n\n\nTimeField\n\n\nA time representation.\n\n\nCorresponds to \ndjango.db.models.fields.TimeField\n\n\nSignature:\n \nTimeField(format=api_settings.TIME_FORMAT, input_formats=None)\n\n\n\n\nformat\n - A string representing the output format. If not specified, this defaults to the same value as the \nTIME_FORMAT\n settings key, which will be \n'iso-8601'\n unless set. Setting to a format string indicates that \nto_representation\n return values should be coerced to string output. Format strings are described below. Setting this value to \nNone\n indicates that Python \ntime\n objects should be returned by \nto_representation\n. In this case the time encoding will be determined by the renderer.\n\n\ninput_formats\n - A list of strings representing the input formats which may be used to parse the date. If not specified, the \nTIME_INPUT_FORMATS\n setting will be used, which defaults to \n['iso-8601']\n.\n\n\n\n\nTimeField\n format strings\n\n\nFormat strings may either be \nPython strftime formats\n which explicitly specify the format, or the special string \n'iso-8601'\n, which indicates that \nISO 8601\n style times should be used. (eg \n'12:34:56.000000'\n)\n\n\nDurationField\n\n\nA Duration representation.\nCorresponds to \ndjango.db.models.fields.DurationField\n\n\nThe \nvalidated_data\n for these fields will contain a \ndatetime.timedelta\n instance.\nThe representation is a string following this format \n'[DD] [HH:[MM:]]ss[.uuuuuu]'\n.\n\n\nNote:\n This field is only available with Django versions \n= 1.8.\n\n\nSignature:\n \nDurationField()\n\n\n\n\nChoice selection fields\n\n\nChoiceField\n\n\nA field that can accept a value out of a limited set of choices.\n\n\nUsed by \nModelSerializer\n to automatically generate fields if the corresponding model field includes a \nchoices=\u2026\n argument.\n\n\nSignature:\n \nChoiceField(choices)\n\n\n\n\nchoices\n - A list of valid values, or a list of \n(key, display_name)\n tuples.\n\n\nallow_blank\n - If set to \nTrue\n then the empty string should be considered a valid value. If set to \nFalse\n then the empty string is considered invalid and will raise a validation error. Defaults to \nFalse\n.\n\n\nhtml_cutoff\n - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Can be used to ensure that automatically generated ChoiceFields with very large possible selections do not prevent a template from rendering. Defaults to \nNone\n.\n\n\nhtml_cutoff_text\n - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to \n\"More than {count} items\u2026\"\n\n\n\n\nBoth the \nallow_blank\n and \nallow_null\n are valid options on \nChoiceField\n, although it is highly recommended that you only use one and not both. \nallow_blank\n should be preferred for textual choices, and \nallow_null\n should be preferred for numeric or other non-textual choices.\n\n\nMultipleChoiceField\n\n\nA field that can accept a set of zero, one or many values, chosen from a limited set of choices. Takes a single mandatory argument. \nto_internal_value\n returns a \nset\n containing the selected values.\n\n\nSignature:\n \nMultipleChoiceField(choices)\n\n\n\n\nchoices\n - A list of valid values, or a list of \n(key, display_name)\n tuples.\n\n\nallow_blank\n - If set to \nTrue\n then the empty string should be considered a valid value. If set to \nFalse\n then the empty string is considered invalid and will raise a validation error. Defaults to \nFalse\n.\n\n\nhtml_cutoff\n - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Can be used to ensure that automatically generated ChoiceFields with very large possible selections do not prevent a template from rendering. Defaults to \nNone\n.\n\n\nhtml_cutoff_text\n - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to \n\"More than {count} items\u2026\"\n\n\n\n\nAs with \nChoiceField\n, both the \nallow_blank\n and \nallow_null\n options are valid, although it is highly recommended that you only use one and not both. \nallow_blank\n should be preferred for textual choices, and \nallow_null\n should be preferred for numeric or other non-textual choices.\n\n\n\n\nFile upload fields\n\n\nParsers and file uploads.\n\n\nThe \nFileField\n and \nImageField\n classes are only suitable for use with \nMultiPartParser\n or \nFileUploadParser\n. Most parsers, such as e.g. JSON don't support file uploads.\nDjango's regular \nFILE_UPLOAD_HANDLERS\n are used for handling uploaded files.\n\n\nFileField\n\n\nA file representation. Performs Django's standard FileField validation.\n\n\nCorresponds to \ndjango.forms.fields.FileField\n.\n\n\nSignature:\n \nFileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)\n\n\n\n\nmax_length\n - Designates the maximum length for the file name.\n\n\nallow_empty_file\n - Designates if empty files are allowed.\n\n\nuse_url\n - If set to \nTrue\n then URL string values will be used for the output representation. If set to \nFalse\n then filename string values will be used for the output representation. Defaults to the value of the \nUPLOADED_FILES_USE_URL\n settings key, which is \nTrue\n unless set otherwise.\n\n\n\n\nImageField\n\n\nAn image representation. Validates the uploaded file content as matching a known image format.\n\n\nCorresponds to \ndjango.forms.fields.ImageField\n.\n\n\nSignature:\n \nImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)\n\n\n\n\nmax_length\n - Designates the maximum length for the file name.\n\n\nallow_empty_file\n - Designates if empty files are allowed.\n\n\nuse_url\n - If set to \nTrue\n then URL string values will be used for the output representation. If set to \nFalse\n then filename string values will be used for the output representation. Defaults to the value of the \nUPLOADED_FILES_USE_URL\n settings key, which is \nTrue\n unless set otherwise.\n\n\n\n\nRequires either the \nPillow\n package or \nPIL\n package. The \nPillow\n package is recommended, as \nPIL\n is no longer actively maintained.\n\n\n\n\nComposite fields\n\n\nListField\n\n\nA field class that validates a list of objects.\n\n\nSignature\n: \nListField(child)\n\n\n\n\nchild\n - A field instance that should be used for validating the objects in the list. If this argument is not provided then objects in the list will not be validated.\n\n\n\n\nFor example, to validate a list of integers you might use something like the following:\n\n\nscores = serializers.ListField(\n child=serializers.IntegerField(min_value=0, max_value=100)\n)\n\n\n\nThe \nListField\n class also supports a declarative style that allows you to write reusable list field classes.\n\n\nclass StringListField(serializers.ListField):\n child = serializers.CharField()\n\n\n\nWe can now reuse our custom \nStringListField\n class throughout our application, without having to provide a \nchild\n argument to it.\n\n\nDictField\n\n\nA field class that validates a dictionary of objects. The keys in \nDictField\n are always assumed to be string values.\n\n\nSignature\n: \nDictField(child)\n\n\n\n\nchild\n - A field instance that should be used for validating the values in the dictionary. If this argument is not provided then values in the mapping will not be validated.\n\n\n\n\nFor example, to create a field that validates a mapping of strings to strings, you would write something like this:\n\n\ndocument = DictField(child=CharField())\n\n\n\nYou can also use the declarative style, as with \nListField\n. For example:\n\n\nclass DocumentField(DictField):\n child = CharField()\n\n\n\nJSONField\n\n\nA field class that validates that the incoming data structure consists of valid JSON primitives. In its alternate binary mode, it will represent and validate JSON-encoded binary strings.\n\n\nSignature\n: \nJSONField(binary)\n\n\n\n\nbinary\n - If set to \nTrue\n then the field will output and validate a JSON encoded string, rather than a primitive data structure. Defaults to \nFalse\n.\n\n\n\n\n\n\nMiscellaneous fields\n\n\nReadOnlyField\n\n\nA field class that simply returns the value of the field without modification.\n\n\nThis field is used by default with \nModelSerializer\n when including field names that relate to an attribute rather than a model field.\n\n\nSignature\n: \nReadOnlyField()\n\n\nFor example, if \nhas_expired\n was a property on the \nAccount\n model, then the following serializer would automatically generate it as a \nReadOnlyField\n:\n\n\nclass AccountSerializer(serializers.ModelSerializer):\n class Meta:\n model = Account\n fields = ('id', 'account_name', 'has_expired')\n\n\n\nHiddenField\n\n\nA field class that does not take a value based on user input, but instead takes its value from a default value or callable.\n\n\nSignature\n: \nHiddenField()\n\n\nFor example, to include a field that always provides the current time as part of the serializer validated data, you would use the following:\n\n\nmodified = serializers.HiddenField(default=timezone.now)\n\n\n\nThe \nHiddenField\n class is usually only needed if you have some validation that needs to run based on some pre-provided field values, but you do not want to expose all of those fields to the end user.\n\n\nFor further examples on \nHiddenField\n see the \nvalidators\n documentation.\n\n\nModelField\n\n\nA generic field that can be tied to any arbitrary model field. The \nModelField\n class delegates the task of serialization/deserialization to its associated model field. This field can be used to create serializer fields for custom model fields, without having to create a new custom serializer field.\n\n\nThis field is used by \nModelSerializer\n to correspond to custom model field classes.\n\n\nSignature:\n \nModelField(model_field=\nDjango ModelField instance\n)\n\n\nThe \nModelField\n class is generally intended for internal use, but can be used by your API if needed. In order to properly instantiate a \nModelField\n, it must be passed a field that is attached to an instantiated model. For example: \nModelField(model_field=MyModel()._meta.get_field('custom_field'))\n\n\nSerializerMethodField\n\n\nThis is a read-only field. It gets its value by calling a method on the serializer class it is attached to. It can be used to add any sort of data to the serialized representation of your object.\n\n\nSignature\n: \nSerializerMethodField(method_name=None)\n\n\n\n\nmethod_name\n - The name of the method on the serializer to be called. If not included this defaults to \nget_\nfield_name\n.\n\n\n\n\nThe serializer method referred to by the \nmethod_name\n argument should accept a single argument (in addition to \nself\n), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:\n\n\nfrom django.contrib.auth.models import User\nfrom django.utils.timezone import now\nfrom rest_framework import serializers\n\nclass UserSerializer(serializers.ModelSerializer):\n days_since_joined = serializers.SerializerMethodField()\n\n class Meta:\n model = User\n\n def get_days_since_joined(self, obj):\n return (now() - obj.date_joined).days\n\n\n\n\n\nCustom fields\n\n\nIf you want to create a custom field, you'll need to subclass \nField\n and then override either one or both of the \n.to_representation()\n and \n.to_internal_value()\n methods. These two methods are used to convert between the initial datatype, and a primitive, serializable datatype. Primitive datatypes will typically be any of a number, string, boolean, \ndate\n/\ntime\n/\ndatetime\n or \nNone\n. They may also be any list or dictionary like object that only contains other primitive objects. Other types might be supported, depending on the renderer that you are using.\n\n\nThe \n.to_representation()\n method is called to convert the initial datatype into a primitive, serializable datatype.\n\n\nThe \nto_internal_value()\n method is called to restore a primitive datatype into its internal python representation. This method should raise a \nserializers.ValidationError\n if the data is invalid.\n\n\nNote that the \nWritableField\n class that was present in version 2.x no longer exists. You should subclass \nField\n and override \nto_internal_value()\n if the field supports data input.\n\n\nExamples\n\n\nLet's look at an example of serializing a class that represents an RGB color value:\n\n\nclass Color(object):\n \"\"\"\n A color represented in the RGB colorspace.\n \"\"\"\n def __init__(self, red, green, blue):\n assert(red \n= 0 and green \n= 0 and blue \n= 0)\n assert(red \n 256 and green \n 256 and blue \n 256)\n self.red, self.green, self.blue = red, green, blue\n\nclass ColorField(serializers.Field):\n \"\"\"\n Color objects are serialized into 'rgb(#, #, #)' notation.\n \"\"\"\n def to_representation(self, obj):\n return \"rgb(%d, %d, %d)\" % (obj.red, obj.green, obj.blue)\n\n def to_internal_value(self, data):\n data = data.strip('rgb(').rstrip(')')\n red, green, blue = [int(col) for col in data.split(',')]\n return Color(red, green, blue)\n\n\n\nBy default field values are treated as mapping to an attribute on the object. If you need to customize how the field value is accessed and set you need to override \n.get_attribute()\n and/or \n.get_value()\n.\n\n\nAs an example, let's create a field that can be used to represent the class name of the object being serialized:\n\n\nclass ClassNameField(serializers.Field):\n def get_attribute(self, obj):\n # We pass the object instance onto `to_representation`,\n # not just the field attribute.\n return obj\n\n def to_representation(self, obj):\n \"\"\"\n Serialize the object's class name.\n \"\"\"\n return obj.__class__.__name__\n\n\n\nRaising validation errors\n\n\nOur \nColorField\n class above currently does not perform any data validation.\nTo indicate invalid data, we should raise a \nserializers.ValidationError\n, like so:\n\n\ndef to_internal_value(self, data):\n if not isinstance(data, six.text_type):\n msg = 'Incorrect type. Expected a string, but got %s'\n raise ValidationError(msg % type(data).__name__)\n\n if not re.match(r'^rgb\\([0-9]+,[0-9]+,[0-9]+\\)$', data):\n raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')\n\n data = data.strip('rgb(').rstrip(')')\n red, green, blue = [int(col) for col in data.split(',')]\n\n if any([col \n 255 or col \n 0 for col in (red, green, blue)]):\n raise ValidationError('Value out of range. Must be between 0 and 255.')\n\n return Color(red, green, blue)\n\n\n\nThe \n.fail()\n method is a shortcut for raising \nValidationError\n that takes a message string from the \nerror_messages\n dictionary. For example:\n\n\ndefault_error_messages = {\n 'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',\n 'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',\n 'out_of_range': 'Value out of range. Must be between 0 and 255.'\n}\n\ndef to_internal_value(self, data):\n if not isinstance(data, six.text_type):\n self.fail('incorrect_type', input_type=type(data).__name__)\n\n if not re.match(r'^rgb\\([0-9]+,[0-9]+,[0-9]+\\)$', data):\n self.fail('incorrect_format')\n\n data = data.strip('rgb(').rstrip(')')\n red, green, blue = [int(col) for col in data.split(',')]\n\n if any([col \n 255 or col \n 0 for col in (red, green, blue)]):\n self.fail('out_of_range')\n\n return Color(red, green, blue)\n\n\n\nThis style keeps you error messages more cleanly separated from your code, and should be preferred.\n\n\nThird party packages\n\n\nThe following third party packages are also available.\n\n\nDRF Compound Fields\n\n\nThe \ndrf-compound-fields\n package provides \"compound\" serializer fields, such as lists of simple values, which can be described by other fields rather than serializers with the \nmany=True\n option. Also provided are fields for typed dictionaries and values that can be either a specific type or a list of items of that type.\n\n\nDRF Extra Fields\n\n\nThe \ndrf-extra-fields\n package provides extra serializer fields for REST framework, including \nBase64ImageField\n and \nPointField\n classes.\n\n\ndjangrestframework-recursive\n\n\nthe \ndjangorestframework-recursive\n package provides a \nRecursiveField\n for serializing and deserializing recursive structures\n\n\ndjango-rest-framework-gis\n\n\nThe \ndjango-rest-framework-gis\n package provides geographic addons for django rest framework like a \nGeometryField\n field and a GeoJSON serializer.\n\n\ndjango-rest-framework-hstore\n\n\nThe \ndjango-rest-framework-hstore\n package provides an \nHStoreField\n to support \ndjango-hstore\n \nDictionaryField\n model field.", "title": "Serializer fields" }, { @@ -1857,7 +1857,7 @@ }, { "location": "/api-guide/fields/#decimalfield", - "text": "A decimal representation, represented in Python by a Decimal instance. Corresponds to django.db.models.fields.DecimalField . Signature : DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits The maximum number of digits allowed in the number. Note that this number must be greater than or equal to decimal_places. decimal_places The number of decimal places to store with the number. coerce_to_string Set to True if string values should be returned for the representation, or False if Decimal objects should be returned. Defaults to the same value as the COERCE_DECIMAL_TO_STRING settings key, which will be True unless overridden. If Decimal objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting localize will force the value to True . max_value Validate that the number provided is no greater than this value. min_value Validate that the number provided is no less than this value. localize Set to True to enable localization of input and output based on the current locale. This will also force coerce_to_string to True . Defaults to False . Note that data formatting is enabled if you have set USE_L10N=True in your settings file.", + "text": "A decimal representation, represented in Python by a Decimal instance. Corresponds to django.db.models.fields.DecimalField . Signature : DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits The maximum number of digits allowed in the number. It must be either None or an integer greater than or equal to decimal_places . decimal_places The number of decimal places to store with the number. coerce_to_string Set to True if string values should be returned for the representation, or False if Decimal objects should be returned. Defaults to the same value as the COERCE_DECIMAL_TO_STRING settings key, which will be True unless overridden. If Decimal objects are returned by the serializer, then the final output format will be determined by the renderer. Note that setting localize will force the value to True . max_value Validate that the number provided is no greater than this value. min_value Validate that the number provided is no less than this value. localize Set to True to enable localization of input and output based on the current locale. This will also force coerce_to_string to True . Defaults to False . Note that data formatting is enabled if you have set USE_L10N=True in your settings file.", "title": "DecimalField" }, { @@ -2037,7 +2037,7 @@ }, { "location": "/api-guide/relations/", - "text": "Serializer relations\n\n\n\n\nBad programmers worry about the code.\nGood programmers worry about data structures and their relationships.\n\n\n \nLinus Torvalds\n\n\n\n\nRelational fields are used to represent model relationships. They can be applied to \nForeignKey\n, \nManyToManyField\n and \nOneToOneField\n relationships, as well as to reverse relationships, and custom relationships such as \nGenericForeignKey\n.\n\n\n\n\nNote:\n The relational fields are declared in \nrelations.py\n, but by convention you should import them from the \nserializers\n module, using \nfrom rest_framework import serializers\n and refer to fields as \nserializers.\nFieldName\n.\n\n\n\n\nInspecting relationships.\n\n\nWhen using the \nModelSerializer\n class, serializer fields and relationships will be automatically generated for you. Inspecting these automatically generated fields can be a useful tool for determining how to customize the relationship style.\n\n\nTo do so, open the Django shell, using \npython manage.py shell\n, then import the serializer class, instantiate it, and print the object representation\u2026\n\n\n from myapp.serializers import AccountSerializer\n\n serializer = AccountSerializer()\n\n print repr(serializer) # Or `print(repr(serializer))` in Python 3.x.\nAccountSerializer():\n id = IntegerField(label='ID', read_only=True)\n name = CharField(allow_blank=True, max_length=100, required=False)\n owner = PrimaryKeyRelatedField(queryset=User.objects.all())\n\n\n\nAPI Reference\n\n\nIn order to explain the various types of relational fields, we'll use a couple of simple models for our examples. Our models will be for music albums, and the tracks listed on each album.\n\n\nclass Album(models.Model):\n album_name = models.CharField(max_length=100)\n artist = models.CharField(max_length=100)\n\nclass Track(models.Model):\n album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)\n order = models.IntegerField()\n title = models.CharField(max_length=100)\n duration = models.IntegerField()\n\n class Meta:\n unique_together = ('album', 'order')\n ordering = ['order']\n\n def __unicode__(self):\n return '%d: %s' % (self.order, self.title)\n\n\n\nStringRelatedField\n\n\nStringRelatedField\n may be used to represent the target of the relationship using its \n__unicode__\n method.\n\n\nFor example, the following serializer.\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.StringRelatedField(many=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to the following representation.\n\n\n{\n 'album_name': 'Things We Lost In The Fire',\n 'artist': 'Low',\n 'tracks': [\n '1: Sunflower',\n '2: Whitetail',\n '3: Dinosaur Act',\n ...\n ]\n}\n\n\n\nThis field is read only.\n\n\nArguments\n:\n\n\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\n\n\nPrimaryKeyRelatedField\n\n\nPrimaryKeyRelatedField\n may be used to represent the target of the relationship using its primary key.\n\n\nFor example, the following serializer:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'Undun',\n 'artist': 'The Roots',\n 'tracks': [\n 89,\n 90,\n 91,\n ...\n ]\n}\n\n\n\nBy default this field is read-write, although you can change this behavior using the \nread_only\n flag.\n\n\nArguments\n:\n\n\n\n\nqueryset\n - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set \nread_only=True\n.\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\nallow_null\n - If set to \nTrue\n, the field will accept values of \nNone\n or the empty string for nullable relationships. Defaults to \nFalse\n.\n\n\npk_field\n - Set to a field to control serialization/deserialization of the primary key's value. For example, \npk_field=UUIDField(format='hex')\n would serialize a UUID primary key into its compact hex representation.\n\n\n\n\nHyperlinkedRelatedField\n\n\nHyperlinkedRelatedField\n may be used to represent the target of the relationship using a hyperlink.\n\n\nFor example, the following serializer:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.HyperlinkedRelatedField(\n many=True,\n read_only=True,\n view_name='track-detail'\n )\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'Graceland',\n 'artist': 'Paul Simon',\n 'tracks': [\n 'http://www.example.com/api/tracks/45/',\n 'http://www.example.com/api/tracks/46/',\n 'http://www.example.com/api/tracks/47/',\n ...\n ]\n}\n\n\n\nBy default this field is read-write, although you can change this behavior using the \nread_only\n flag.\n\n\n\n\nNote\n: This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the \nlookup_field\n and \nlookup_url_kwarg\n arguments.\n\n\nThis is suitable for URLs that contain a single primary key or slug argument as part of the URL.\n\n\nIf you require more complex hyperlinked representation you'll need to customize the field, as described in the \ncustom hyperlinked fields\n section, below.\n\n\n\n\nArguments\n:\n\n\n\n\nview_name\n - The view name that should be used as the target of the relationship. If you're using \nthe standard router classes\n this will be a string with the format \nmodelname\n-detail\n. \nrequired\n.\n\n\nqueryset\n - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set \nread_only=True\n.\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\nallow_null\n - If set to \nTrue\n, the field will accept values of \nNone\n or the empty string for nullable relationships. Defaults to \nFalse\n.\n\n\nlookup_field\n - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is \n'pk'\n.\n\n\nlookup_url_kwarg\n - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as \nlookup_field\n.\n\n\nformat\n - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the \nformat\n argument.\n\n\n\n\nSlugRelatedField\n\n\nSlugRelatedField\n may be used to represent the target of the relationship using a field on the target.\n\n\nFor example, the following serializer:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.SlugRelatedField(\n many=True,\n read_only=True,\n slug_field='title'\n )\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'Dear John',\n 'artist': 'Loney Dear',\n 'tracks': [\n 'Airport Surroundings',\n 'Everything Turns to You',\n 'I Was Only Going Out',\n ...\n ]\n}\n\n\n\nBy default this field is read-write, although you can change this behavior using the \nread_only\n flag.\n\n\nWhen using \nSlugRelatedField\n as a read-write field, you will normally want to ensure that the slug field corresponds to a model field with \nunique=True\n.\n\n\nArguments\n:\n\n\n\n\nslug_field\n - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, \nusername\n. \nrequired\n\n\nqueryset\n - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set \nread_only=True\n.\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\nallow_null\n - If set to \nTrue\n, the field will accept values of \nNone\n or the empty string for nullable relationships. Defaults to \nFalse\n.\n\n\n\n\nHyperlinkedIdentityField\n\n\nThis field can be applied as an identity relationship, such as the \n'url'\n field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer:\n\n\nclass AlbumSerializer(serializers.HyperlinkedModelSerializer):\n track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'track_listing')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'The Eraser',\n 'artist': 'Thom Yorke',\n 'track_listing': 'http://www.example.com/api/track_list/12/',\n}\n\n\n\nThis field is always read-only.\n\n\nArguments\n:\n\n\n\n\nview_name\n - The view name that should be used as the target of the relationship. If you're using \nthe standard router classes\n this will be a string with the format \nmodel_name\n-detail\n. \nrequired\n.\n\n\nlookup_field\n - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is \n'pk'\n.\n\n\nlookup_url_kwarg\n - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as \nlookup_field\n.\n\n\nformat\n - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the \nformat\n argument.\n\n\n\n\n\n\nNested relationships\n\n\nNested relationships can be expressed by using serializers as fields.\n\n\nIf the field is used to represent a to-many relationship, you should add the \nmany=True\n flag to the serializer field.\n\n\nExample\n\n\nFor example, the following serializer:\n\n\nclass TrackSerializer(serializers.ModelSerializer):\n class Meta:\n model = Track\n fields = ('order', 'title', 'duration')\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = TrackSerializer(many=True, read_only=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a nested representation like this:\n\n\n album = Album.objects.create(album_name=\"The Grey Album\", artist='Danger Mouse')\n\n Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)\n\nTrack: Track object\n\n\n Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)\n\nTrack: Track object\n\n\n Track.objects.create(album=album, order=3, title='Encore', duration=159)\n\nTrack: Track object\n\n\n serializer = AlbumSerializer(instance=album)\n\n serializer.data\n{\n 'album_name': 'The Grey Album',\n 'artist': 'Danger Mouse',\n 'tracks': [\n {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},\n {'order': 2, 'title': 'What More Can I Say', 'duration': 264},\n {'order': 3, 'title': 'Encore', 'duration': 159},\n ...\n ],\n}\n\n\n\nWritable nested serializers\n\n\nBy default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create \ncreate()\n and/or \nupdate()\n methods in order to explicitly specify how the child relationships should be saved.\n\n\nclass TrackSerializer(serializers.ModelSerializer):\n class Meta:\n model = Track\n fields = ('order', 'title', 'duration')\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = TrackSerializer(many=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n def create(self, validated_data):\n tracks_data = validated_data.pop('tracks')\n album = Album.objects.create(**validated_data)\n for track_data in tracks_data:\n Track.objects.create(album=album, **track_data)\n return album\n\n\n data = {\n 'album_name': 'The Grey Album',\n 'artist': 'Danger Mouse',\n 'tracks': [\n {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},\n {'order': 2, 'title': 'What More Can I Say', 'duration': 264},\n {'order': 3, 'title': 'Encore', 'duration': 159},\n ],\n}\n\n serializer = AlbumSerializer(data=data)\n\n serializer.is_valid()\nTrue\n\n serializer.save()\n\nAlbum: Album object\n\n\n\n\n\n\nCustom relational fields\n\n\nIn rare cases where none of the existing relational styles fit the representation you need,\nyou can implement a completely custom relational field, that describes exactly how the\noutput representation should be generated from the model instance.\n\n\nTo implement a custom relational field, you should override \nRelatedField\n, and implement the \n.to_representation(self, value)\n method. This method takes the target of the field as the \nvalue\n argument, and should return the representation that should be used to serialize the target. The \nvalue\n argument will typically be a model instance.\n\n\nIf you want to implement a read-write relational field, you must also implement the \n.to_internal_value(self, data)\n method.\n\n\nTo provide a dynamic queryset based on the \ncontext\n, you can also override \n.get_queryset(self)\n instead of specifying \n.queryset\n on the class or when initializing the field.\n\n\nExample\n\n\nFor example, we could define a relational field to serialize a track to a custom string representation, using its ordering, title, and duration.\n\n\nimport time\n\nclass TrackListingField(serializers.RelatedField):\n def to_representation(self, value):\n duration = time.strftime('%M:%S', time.gmtime(value.duration))\n return 'Track %d: %s (%s)' % (value.order, value.name, duration)\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = TrackListingField(many=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nThis custom field would then serialize to the following representation.\n\n\n{\n 'album_name': 'Sometimes I Wish We Were an Eagle',\n 'artist': 'Bill Callahan',\n 'tracks': [\n 'Track 1: Jim Cain (04:39)',\n 'Track 2: Eid Ma Clack Shaw (04:19)',\n 'Track 3: The Wind and the Dove (04:34)',\n ...\n ]\n}\n\n\n\n\n\nCustom hyperlinked fields\n\n\nIn some cases you may need to customize the behavior of a hyperlinked field, in order to represent URLs that require more than a single lookup field.\n\n\nYou can achieve this by overriding \nHyperlinkedRelatedField\n. There are two methods that may be overridden:\n\n\nget_url(self, obj, view_name, request, format)\n\n\nThe \nget_url\n method is used to map the object instance to its URL representation.\n\n\nMay raise a \nNoReverseMatch\n if the \nview_name\n and \nlookup_field\n\nattributes are not configured to correctly match the URL conf.\n\n\nget_object(self, queryset, view_name, view_args, view_kwargs)\n\n\nIf you want to support a writable hyperlinked field then you'll also want to override \nget_object\n, in order to map incoming URLs back to the object they represent. For read-only hyperlinked fields there is no need to override this method.\n\n\nThe return value of this method should the object that corresponds to the matched URL conf arguments.\n\n\nMay raise an \nObjectDoesNotExist\n exception.\n\n\nExample\n\n\nSay we have a URL for a customer object that takes two keyword arguments, like so:\n\n\n/api/\norganization_slug\n/customers/\ncustomer_pk\n/\n\n\n\nThis cannot be represented with the default implementation, which accepts only a single lookup field.\n\n\nIn this case we'd need to override \nHyperlinkedRelatedField\n to get the behavior we want:\n\n\nfrom rest_framework import serializers\nfrom rest_framework.reverse import reverse\n\nclass CustomerHyperlink(serializers.HyperlinkedRelatedField):\n # We define these as class attributes, so we don't need to pass them as arguments.\n view_name = 'customer-detail'\n queryset = Customer.objects.all()\n\n def get_url(self, obj, view_name, request, format):\n url_kwargs = {\n 'organization_slug': obj.organization.slug,\n 'customer_pk': obj.pk\n }\n return reverse(view_name, kwargs=url_kwargs, request=request, format=format)\n\n def get_object(self, view_name, view_args, view_kwargs):\n lookup_kwargs = {\n 'organization__slug': view_kwargs['organization_slug'],\n 'pk': view_kwargs['customer_pk']\n }\n return self.get_queryset().get(**lookup_kwargs)\n\n\n\nNote that if you wanted to use this style together with the generic views then you'd also need to override \n.get_object\n on the view in order to get the correct lookup behavior.\n\n\nGenerally we recommend a flat style for API representations where possible, but the nested URL style can also be reasonable when used in moderation.\n\n\n\n\nFurther notes\n\n\nThe \nqueryset\n argument\n\n\nThe \nqueryset\n argument is only ever required for \nwritable\n relationship field, in which case it is used for performing the model instance lookup, that maps from the primitive user input, into a model instance.\n\n\nIn version 2.x a serializer class could \nsometimes\n automatically determine the \nqueryset\n argument \nif\n a \nModelSerializer\n class was being used.\n\n\nThis behavior is now replaced with \nalways\n using an explicit \nqueryset\n argument for writable relational fields.\n\n\nDoing so reduces the amount of hidden 'magic' that \nModelSerializer\n provides, makes the behavior of the field more clear, and ensures that it is trivial to move between using the \nModelSerializer\n shortcut, or using fully explicit \nSerializer\n classes.\n\n\nCustomizing the HTML display\n\n\nThe built-in \n__str__\n method of the model will be used to generate string representations of the objects used to populate the \nchoices\n property. These choices are used to populate select HTML inputs in the browsable API.\n\n\nTo provide customized representations for such inputs, override \ndisplay_value()\n of a \nRelatedField\n subclass. This method will receive a model object, and should return a string suitable for representing it. For example:\n\n\nclass TrackPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):\n def display_value(self, instance):\n return 'Track: %s' % (instance.title)\n\n\n\nSelect field cutoffs\n\n\nWhen rendered in the browsable API relational fields will default to only displaying a maximum of 1000 selectable items. If more items are present then a disabled option with \"More than 1000 items\u2026\" will be displayed.\n\n\nThis behavior is intended to prevent a template from being unable to render in an acceptable timespan due to a very large number of relationships being displayed.\n\n\nThere are two keyword arguments you can use to control this behavior:\n\n\n\n\nhtml_cutoff\n - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Set to \nNone\n to disable any limiting. Defaults to \n1000\n.\n\n\nhtml_cutoff_text\n - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to \n\"More than {count} items\u2026\"\n\n\n\n\nYou can also control these globally using the settings \nHTML_SELECT_CUTOFF\n and \nHTML_SELECT_CUTOFF_TEXT\n.\n\n\nIn cases where the cutoff is being enforced you may want to instead use a plain input field in the HTML form. You can do so using the \nstyle\n keyword argument. For example:\n\n\nassigned_to = serializers.SlugRelatedField(\n queryset=User.objects.all(),\n slug_field='username',\n style={'base_template': 'input.html'}\n)\n\n\n\nReverse relations\n\n\nNote that reverse relationships are not automatically included by the \nModelSerializer\n and \nHyperlinkedModelSerializer\n classes. To include a reverse relationship, you must explicitly add it to the fields list. For example:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n class Meta:\n fields = ('tracks', ...)\n\n\n\nYou'll normally want to ensure that you've set an appropriate \nrelated_name\n argument on the relationship, that you can use as the field name. For example:\n\n\nclass Track(models.Model):\n album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)\n ...\n\n\n\nIf you have not set a related name for the reverse relationship, you'll need to use the automatically generated related name in the \nfields\n argument. For example:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n class Meta:\n fields = ('track_set', ...)\n\n\n\nSee the Django documentation on \nreverse relationships\n for more details.\n\n\nGeneric relationships\n\n\nIf you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want to serialize the targets of the relationship.\n\n\nFor example, given the following model for a tag, which has a generic relationship with other arbitrary models:\n\n\nclass TaggedItem(models.Model):\n \"\"\"\n Tags arbitrary model instances using a generic relation.\n\n See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/\n \"\"\"\n tag_name = models.SlugField()\n content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)\n object_id = models.PositiveIntegerField()\n tagged_object = GenericForeignKey('content_type', 'object_id')\n\n def __unicode__(self):\n return self.tag_name\n\n\n\nAnd the following two models, which may have associated tags:\n\n\nclass Bookmark(models.Model):\n \"\"\"\n A bookmark consists of a URL, and 0 or more descriptive tags.\n \"\"\"\n url = models.URLField()\n tags = GenericRelation(TaggedItem)\n\n\nclass Note(models.Model):\n \"\"\"\n A note consists of some text, and 0 or more descriptive tags.\n \"\"\"\n text = models.CharField(max_length=1000)\n tags = GenericRelation(TaggedItem)\n\n\n\nWe could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized.\n\n\nclass TaggedObjectRelatedField(serializers.RelatedField):\n \"\"\"\n A custom field to use for the `tagged_object` generic relationship.\n \"\"\"\n\n def to_representation(self, value):\n \"\"\"\n Serialize tagged objects to a simple textual representation.\n \"\"\"\n if isinstance(value, Bookmark):\n return 'Bookmark: ' + value.url\n elif isinstance(value, Note):\n return 'Note: ' + value.text\n raise Exception('Unexpected type of tagged object')\n\n\n\nIf you need the target of the relationship to have a nested representation, you can use the required serializers inside the \n.to_representation()\n method:\n\n\n def to_representation(self, value):\n \"\"\"\n Serialize bookmark instances using a bookmark serializer,\n and note instances using a note serializer.\n \"\"\"\n if isinstance(value, Bookmark):\n serializer = BookmarkSerializer(value)\n elif isinstance(value, Note):\n serializer = NoteSerializer(value)\n else:\n raise Exception('Unexpected type of tagged object')\n\n return serializer.data\n\n\n\nNote that reverse generic keys, expressed using the \nGenericRelation\n field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known.\n\n\nFor more information see \nthe Django documentation on generic relations\n.\n\n\nManyToManyFields with a Through Model\n\n\nBy default, relational fields that target a \nManyToManyField\n with a\n\nthrough\n model specified are set to read-only.\n\n\nIf you explicitly specify a relational field pointing to a\n\nManyToManyField\n with a through model, be sure to set \nread_only\n\nto \nTrue\n.\n\n\n\n\nThird Party Packages\n\n\nThe following third party packages are also available.\n\n\nDRF Nested Routers\n\n\nThe \ndrf-nested-routers package\n provides routers and relationship fields for working with nested resources.\n\n\nRest Framework Generic Relations\n\n\nThe \nrest-framework-generic-relations\n library provides read/write serialization for generic foreign keys.", + "text": "Serializer relations\n\n\n\n\nBad programmers worry about the code.\nGood programmers worry about data structures and their relationships.\n\n\n \nLinus Torvalds\n\n\n\n\nRelational fields are used to represent model relationships. They can be applied to \nForeignKey\n, \nManyToManyField\n and \nOneToOneField\n relationships, as well as to reverse relationships, and custom relationships such as \nGenericForeignKey\n.\n\n\n\n\nNote:\n The relational fields are declared in \nrelations.py\n, but by convention you should import them from the \nserializers\n module, using \nfrom rest_framework import serializers\n and refer to fields as \nserializers.\nFieldName\n.\n\n\n\n\nInspecting relationships.\n\n\nWhen using the \nModelSerializer\n class, serializer fields and relationships will be automatically generated for you. Inspecting these automatically generated fields can be a useful tool for determining how to customize the relationship style.\n\n\nTo do so, open the Django shell, using \npython manage.py shell\n, then import the serializer class, instantiate it, and print the object representation\u2026\n\n\n from myapp.serializers import AccountSerializer\n\n serializer = AccountSerializer()\n\n print repr(serializer) # Or `print(repr(serializer))` in Python 3.x.\nAccountSerializer():\n id = IntegerField(label='ID', read_only=True)\n name = CharField(allow_blank=True, max_length=100, required=False)\n owner = PrimaryKeyRelatedField(queryset=User.objects.all())\n\n\n\nAPI Reference\n\n\nIn order to explain the various types of relational fields, we'll use a couple of simple models for our examples. Our models will be for music albums, and the tracks listed on each album.\n\n\nclass Album(models.Model):\n album_name = models.CharField(max_length=100)\n artist = models.CharField(max_length=100)\n\nclass Track(models.Model):\n album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)\n order = models.IntegerField()\n title = models.CharField(max_length=100)\n duration = models.IntegerField()\n\n class Meta:\n unique_together = ('album', 'order')\n ordering = ['order']\n\n def __unicode__(self):\n return '%d: %s' % (self.order, self.title)\n\n\n\nStringRelatedField\n\n\nStringRelatedField\n may be used to represent the target of the relationship using its \n__unicode__\n method.\n\n\nFor example, the following serializer.\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.StringRelatedField(many=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to the following representation.\n\n\n{\n 'album_name': 'Things We Lost In The Fire',\n 'artist': 'Low',\n 'tracks': [\n '1: Sunflower',\n '2: Whitetail',\n '3: Dinosaur Act',\n ...\n ]\n}\n\n\n\nThis field is read only.\n\n\nArguments\n:\n\n\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\n\n\nPrimaryKeyRelatedField\n\n\nPrimaryKeyRelatedField\n may be used to represent the target of the relationship using its primary key.\n\n\nFor example, the following serializer:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'Undun',\n 'artist': 'The Roots',\n 'tracks': [\n 89,\n 90,\n 91,\n ...\n ]\n}\n\n\n\nBy default this field is read-write, although you can change this behavior using the \nread_only\n flag.\n\n\nArguments\n:\n\n\n\n\nqueryset\n - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set \nread_only=True\n.\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\nallow_null\n - If set to \nTrue\n, the field will accept values of \nNone\n or the empty string for nullable relationships. Defaults to \nFalse\n.\n\n\npk_field\n - Set to a field to control serialization/deserialization of the primary key's value. For example, \npk_field=UUIDField(format='hex')\n would serialize a UUID primary key into its compact hex representation.\n\n\n\n\nHyperlinkedRelatedField\n\n\nHyperlinkedRelatedField\n may be used to represent the target of the relationship using a hyperlink.\n\n\nFor example, the following serializer:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.HyperlinkedRelatedField(\n many=True,\n read_only=True,\n view_name='track-detail'\n )\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'Graceland',\n 'artist': 'Paul Simon',\n 'tracks': [\n 'http://www.example.com/api/tracks/45/',\n 'http://www.example.com/api/tracks/46/',\n 'http://www.example.com/api/tracks/47/',\n ...\n ]\n}\n\n\n\nBy default this field is read-write, although you can change this behavior using the \nread_only\n flag.\n\n\n\n\nNote\n: This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the \nlookup_field\n and \nlookup_url_kwarg\n arguments.\n\n\nThis is suitable for URLs that contain a single primary key or slug argument as part of the URL.\n\n\nIf you require more complex hyperlinked representation you'll need to customize the field, as described in the \ncustom hyperlinked fields\n section, below.\n\n\n\n\nArguments\n:\n\n\n\n\nview_name\n - The view name that should be used as the target of the relationship. If you're using \nthe standard router classes\n this will be a string with the format \nmodelname\n-detail\n. \nrequired\n.\n\n\nqueryset\n - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set \nread_only=True\n.\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\nallow_null\n - If set to \nTrue\n, the field will accept values of \nNone\n or the empty string for nullable relationships. Defaults to \nFalse\n.\n\n\nlookup_field\n - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is \n'pk'\n.\n\n\nlookup_url_kwarg\n - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as \nlookup_field\n.\n\n\nformat\n - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the \nformat\n argument.\n\n\n\n\nSlugRelatedField\n\n\nSlugRelatedField\n may be used to represent the target of the relationship using a field on the target.\n\n\nFor example, the following serializer:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = serializers.SlugRelatedField(\n many=True,\n read_only=True,\n slug_field='title'\n )\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'Dear John',\n 'artist': 'Loney Dear',\n 'tracks': [\n 'Airport Surroundings',\n 'Everything Turns to You',\n 'I Was Only Going Out',\n ...\n ]\n}\n\n\n\nBy default this field is read-write, although you can change this behavior using the \nread_only\n flag.\n\n\nWhen using \nSlugRelatedField\n as a read-write field, you will normally want to ensure that the slug field corresponds to a model field with \nunique=True\n.\n\n\nArguments\n:\n\n\n\n\nslug_field\n - The field on the target that should be used to represent it. This should be a field that uniquely identifies any given instance. For example, \nusername\n. \nrequired\n\n\nqueryset\n - The queryset used for model instance lookups when validating the field input. Relationships must either set a queryset explicitly, or set \nread_only=True\n.\n\n\nmany\n - If applied to a to-many relationship, you should set this argument to \nTrue\n.\n\n\nallow_null\n - If set to \nTrue\n, the field will accept values of \nNone\n or the empty string for nullable relationships. Defaults to \nFalse\n.\n\n\n\n\nHyperlinkedIdentityField\n\n\nThis field can be applied as an identity relationship, such as the \n'url'\n field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer:\n\n\nclass AlbumSerializer(serializers.HyperlinkedModelSerializer):\n track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'track_listing')\n\n\n\nWould serialize to a representation like this:\n\n\n{\n 'album_name': 'The Eraser',\n 'artist': 'Thom Yorke',\n 'track_listing': 'http://www.example.com/api/track_list/12/',\n}\n\n\n\nThis field is always read-only.\n\n\nArguments\n:\n\n\n\n\nview_name\n - The view name that should be used as the target of the relationship. If you're using \nthe standard router classes\n this will be a string with the format \nmodel_name\n-detail\n. \nrequired\n.\n\n\nlookup_field\n - The field on the target that should be used for the lookup. Should correspond to a URL keyword argument on the referenced view. Default is \n'pk'\n.\n\n\nlookup_url_kwarg\n - The name of the keyword argument defined in the URL conf that corresponds to the lookup field. Defaults to using the same value as \nlookup_field\n.\n\n\nformat\n - If using format suffixes, hyperlinked fields will use the same format suffix for the target unless overridden by using the \nformat\n argument.\n\n\n\n\n\n\nNested relationships\n\n\nNested relationships can be expressed by using serializers as fields.\n\n\nIf the field is used to represent a to-many relationship, you should add the \nmany=True\n flag to the serializer field.\n\n\nExample\n\n\nFor example, the following serializer:\n\n\nclass TrackSerializer(serializers.ModelSerializer):\n class Meta:\n model = Track\n fields = ('order', 'title', 'duration')\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = TrackSerializer(many=True, read_only=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nWould serialize to a nested representation like this:\n\n\n album = Album.objects.create(album_name=\"The Grey Album\", artist='Danger Mouse')\n\n Track.objects.create(album=album, order=1, title='Public Service Announcement', duration=245)\n\nTrack: Track object\n\n\n Track.objects.create(album=album, order=2, title='What More Can I Say', duration=264)\n\nTrack: Track object\n\n\n Track.objects.create(album=album, order=3, title='Encore', duration=159)\n\nTrack: Track object\n\n\n serializer = AlbumSerializer(instance=album)\n\n serializer.data\n{\n 'album_name': 'The Grey Album',\n 'artist': 'Danger Mouse',\n 'tracks': [\n {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},\n {'order': 2, 'title': 'What More Can I Say', 'duration': 264},\n {'order': 3, 'title': 'Encore', 'duration': 159},\n ...\n ],\n}\n\n\n\nWritable nested serializers\n\n\nBy default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create \ncreate()\n and/or \nupdate()\n methods in order to explicitly specify how the child relationships should be saved.\n\n\nclass TrackSerializer(serializers.ModelSerializer):\n class Meta:\n model = Track\n fields = ('order', 'title', 'duration')\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = TrackSerializer(many=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n def create(self, validated_data):\n tracks_data = validated_data.pop('tracks')\n album = Album.objects.create(**validated_data)\n for track_data in tracks_data:\n Track.objects.create(album=album, **track_data)\n return album\n\n\n data = {\n 'album_name': 'The Grey Album',\n 'artist': 'Danger Mouse',\n 'tracks': [\n {'order': 1, 'title': 'Public Service Announcement', 'duration': 245},\n {'order': 2, 'title': 'What More Can I Say', 'duration': 264},\n {'order': 3, 'title': 'Encore', 'duration': 159},\n ],\n}\n\n serializer = AlbumSerializer(data=data)\n\n serializer.is_valid()\nTrue\n\n serializer.save()\n\nAlbum: Album object\n\n\n\n\n\n\nCustom relational fields\n\n\nIn rare cases where none of the existing relational styles fit the representation you need,\nyou can implement a completely custom relational field, that describes exactly how the\noutput representation should be generated from the model instance.\n\n\nTo implement a custom relational field, you should override \nRelatedField\n, and implement the \n.to_representation(self, value)\n method. This method takes the target of the field as the \nvalue\n argument, and should return the representation that should be used to serialize the target. The \nvalue\n argument will typically be a model instance.\n\n\nIf you want to implement a read-write relational field, you must also implement the \n.to_internal_value(self, data)\n method.\n\n\nTo provide a dynamic queryset based on the \ncontext\n, you can also override \n.get_queryset(self)\n instead of specifying \n.queryset\n on the class or when initializing the field.\n\n\nExample\n\n\nFor example, we could define a relational field to serialize a track to a custom string representation, using its ordering, title, and duration.\n\n\nimport time\n\nclass TrackListingField(serializers.RelatedField):\n def to_representation(self, value):\n duration = time.strftime('%M:%S', time.gmtime(value.duration))\n return 'Track %d: %s (%s)' % (value.order, value.name, duration)\n\nclass AlbumSerializer(serializers.ModelSerializer):\n tracks = TrackListingField(many=True)\n\n class Meta:\n model = Album\n fields = ('album_name', 'artist', 'tracks')\n\n\n\nThis custom field would then serialize to the following representation.\n\n\n{\n 'album_name': 'Sometimes I Wish We Were an Eagle',\n 'artist': 'Bill Callahan',\n 'tracks': [\n 'Track 1: Jim Cain (04:39)',\n 'Track 2: Eid Ma Clack Shaw (04:19)',\n 'Track 3: The Wind and the Dove (04:34)',\n ...\n ]\n}\n\n\n\n\n\nCustom hyperlinked fields\n\n\nIn some cases you may need to customize the behavior of a hyperlinked field, in order to represent URLs that require more than a single lookup field.\n\n\nYou can achieve this by overriding \nHyperlinkedRelatedField\n. There are two methods that may be overridden:\n\n\nget_url(self, obj, view_name, request, format)\n\n\nThe \nget_url\n method is used to map the object instance to its URL representation.\n\n\nMay raise a \nNoReverseMatch\n if the \nview_name\n and \nlookup_field\n\nattributes are not configured to correctly match the URL conf.\n\n\nget_object(self, queryset, view_name, view_args, view_kwargs)\n\n\nIf you want to support a writable hyperlinked field then you'll also want to override \nget_object\n, in order to map incoming URLs back to the object they represent. For read-only hyperlinked fields there is no need to override this method.\n\n\nThe return value of this method should the object that corresponds to the matched URL conf arguments.\n\n\nMay raise an \nObjectDoesNotExist\n exception.\n\n\nExample\n\n\nSay we have a URL for a customer object that takes two keyword arguments, like so:\n\n\n/api/\norganization_slug\n/customers/\ncustomer_pk\n/\n\n\n\nThis cannot be represented with the default implementation, which accepts only a single lookup field.\n\n\nIn this case we'd need to override \nHyperlinkedRelatedField\n to get the behavior we want:\n\n\nfrom rest_framework import serializers\nfrom rest_framework.reverse import reverse\n\nclass CustomerHyperlink(serializers.HyperlinkedRelatedField):\n # We define these as class attributes, so we don't need to pass them as arguments.\n view_name = 'customer-detail'\n queryset = Customer.objects.all()\n\n def get_url(self, obj, view_name, request, format):\n url_kwargs = {\n 'organization_slug': obj.organization.slug,\n 'customer_pk': obj.pk\n }\n return reverse(view_name, kwargs=url_kwargs, request=request, format=format)\n\n def get_object(self, view_name, view_args, view_kwargs):\n lookup_kwargs = {\n 'organization__slug': view_kwargs['organization_slug'],\n 'pk': view_kwargs['customer_pk']\n }\n return self.get_queryset().get(**lookup_kwargs)\n\n\n\nNote that if you wanted to use this style together with the generic views then you'd also need to override \n.get_object\n on the view in order to get the correct lookup behavior.\n\n\nGenerally we recommend a flat style for API representations where possible, but the nested URL style can also be reasonable when used in moderation.\n\n\n\n\nFurther notes\n\n\nThe \nqueryset\n argument\n\n\nThe \nqueryset\n argument is only ever required for \nwritable\n relationship field, in which case it is used for performing the model instance lookup, that maps from the primitive user input, into a model instance.\n\n\nIn version 2.x a serializer class could \nsometimes\n automatically determine the \nqueryset\n argument \nif\n a \nModelSerializer\n class was being used.\n\n\nThis behavior is now replaced with \nalways\n using an explicit \nqueryset\n argument for writable relational fields.\n\n\nDoing so reduces the amount of hidden 'magic' that \nModelSerializer\n provides, makes the behavior of the field more clear, and ensures that it is trivial to move between using the \nModelSerializer\n shortcut, or using fully explicit \nSerializer\n classes.\n\n\nCustomizing the HTML display\n\n\nThe built-in \n__str__\n method of the model will be used to generate string representations of the objects used to populate the \nchoices\n property. These choices are used to populate select HTML inputs in the browsable API.\n\n\nTo provide customized representations for such inputs, override \ndisplay_value()\n of a \nRelatedField\n subclass. This method will receive a model object, and should return a string suitable for representing it. For example:\n\n\nclass TrackPrimaryKeyRelatedField(serializers.PrimaryKeyRelatedField):\n def display_value(self, instance):\n return 'Track: %s' % (instance.title)\n\n\n\nSelect field cutoffs\n\n\nWhen rendered in the browsable API relational fields will default to only displaying a maximum of 1000 selectable items. If more items are present then a disabled option with \"More than 1000 items\u2026\" will be displayed.\n\n\nThis behavior is intended to prevent a template from being unable to render in an acceptable timespan due to a very large number of relationships being displayed.\n\n\nThere are two keyword arguments you can use to control this behavior:\n\n\n\n\nhtml_cutoff\n - If set this will be the maximum number of choices that will be displayed by a HTML select drop down. Set to \nNone\n to disable any limiting. Defaults to \n1000\n.\n\n\nhtml_cutoff_text\n - If set this will display a textual indicator if the maximum number of items have been cutoff in an HTML select drop down. Defaults to \n\"More than {count} items\u2026\"\n\n\n\n\nYou can also control these globally using the settings \nHTML_SELECT_CUTOFF\n and \nHTML_SELECT_CUTOFF_TEXT\n.\n\n\nIn cases where the cutoff is being enforced you may want to instead use a plain input field in the HTML form. You can do so using the \nstyle\n keyword argument. For example:\n\n\nassigned_to = serializers.SlugRelatedField(\n queryset=User.objects.all(),\n slug_field='username',\n style={'base_template': 'input.html'}\n)\n\n\n\nReverse relations\n\n\nNote that reverse relationships are not automatically included by the \nModelSerializer\n and \nHyperlinkedModelSerializer\n classes. To include a reverse relationship, you must explicitly add it to the fields list. For example:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n class Meta:\n fields = ('tracks', ...)\n\n\n\nYou'll normally want to ensure that you've set an appropriate \nrelated_name\n argument on the relationship, that you can use as the field name. For example:\n\n\nclass Track(models.Model):\n album = models.ForeignKey(Album, related_name='tracks', on_delete=models.CASCADE)\n ...\n\n\n\nIf you have not set a related name for the reverse relationship, you'll need to use the automatically generated related name in the \nfields\n argument. For example:\n\n\nclass AlbumSerializer(serializers.ModelSerializer):\n class Meta:\n fields = ('track_set', ...)\n\n\n\nSee the Django documentation on \nreverse relationships\n for more details.\n\n\nGeneric relationships\n\n\nIf you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want to serialize the targets of the relationship.\n\n\nFor example, given the following model for a tag, which has a generic relationship with other arbitrary models:\n\n\nclass TaggedItem(models.Model):\n \"\"\"\n Tags arbitrary model instances using a generic relation.\n\n See: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/\n \"\"\"\n tag_name = models.SlugField()\n content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)\n object_id = models.PositiveIntegerField()\n tagged_object = GenericForeignKey('content_type', 'object_id')\n\n def __unicode__(self):\n return self.tag_name\n\n\n\nAnd the following two models, which may have associated tags:\n\n\nclass Bookmark(models.Model):\n \"\"\"\n A bookmark consists of a URL, and 0 or more descriptive tags.\n \"\"\"\n url = models.URLField()\n tags = GenericRelation(TaggedItem)\n\n\nclass Note(models.Model):\n \"\"\"\n A note consists of some text, and 0 or more descriptive tags.\n \"\"\"\n text = models.CharField(max_length=1000)\n tags = GenericRelation(TaggedItem)\n\n\n\nWe could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized.\n\n\nclass TaggedObjectRelatedField(serializers.RelatedField):\n \"\"\"\n A custom field to use for the `tagged_object` generic relationship.\n \"\"\"\n\n def to_representation(self, value):\n \"\"\"\n Serialize tagged objects to a simple textual representation.\n \"\"\"\n if isinstance(value, Bookmark):\n return 'Bookmark: ' + value.url\n elif isinstance(value, Note):\n return 'Note: ' + value.text\n raise Exception('Unexpected type of tagged object')\n\n\n\nIf you need the target of the relationship to have a nested representation, you can use the required serializers inside the \n.to_representation()\n method:\n\n\n def to_representation(self, value):\n \"\"\"\n Serialize bookmark instances using a bookmark serializer,\n and note instances using a note serializer.\n \"\"\"\n if isinstance(value, Bookmark):\n serializer = BookmarkSerializer(value)\n elif isinstance(value, Note):\n serializer = NoteSerializer(value)\n else:\n raise Exception('Unexpected type of tagged object')\n\n return serializer.data\n\n\n\nNote that reverse generic keys, expressed using the \nGenericRelation\n field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known.\n\n\nFor more information see \nthe Django documentation on generic relations\n.\n\n\nManyToManyFields with a Through Model\n\n\nBy default, relational fields that target a \nManyToManyField\n with a\n\nthrough\n model specified are set to read-only.\n\n\nIf you explicitly specify a relational field pointing to a\n\nManyToManyField\n with a through model, be sure to set \nread_only\n\nto \nTrue\n.\n\n\n\n\nThird Party Packages\n\n\nThe following third party packages are also available.\n\n\nDRF Nested Routers\n\n\nThe \ndrf-nested-routers package\n provides routers and relationship fields for working with nested resources.\n\n\nRest Framework Generic Relations\n\n\nThe \nrest-framework-generic-relations\n library provides read/write serialization for generic foreign keys.", "title": "Serializer relations" }, { @@ -2142,7 +2142,7 @@ }, { "location": "/api-guide/relations/#generic-relationships", - "text": "If you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want to serialize the targets of the relationship. For example, given the following model for a tag, which has a generic relationship with other arbitrary models: class TaggedItem(models.Model):\n \"\"\"\n Tags arbitrary model instances using a generic relation.\n\n See: https://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/\n \"\"\"\n tag_name = models.SlugField()\n content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)\n object_id = models.PositiveIntegerField()\n tagged_object = GenericForeignKey('content_type', 'object_id')\n\n def __unicode__(self):\n return self.tag_name And the following two models, which may have associated tags: class Bookmark(models.Model):\n \"\"\"\n A bookmark consists of a URL, and 0 or more descriptive tags.\n \"\"\"\n url = models.URLField()\n tags = GenericRelation(TaggedItem)\n\n\nclass Note(models.Model):\n \"\"\"\n A note consists of some text, and 0 or more descriptive tags.\n \"\"\"\n text = models.CharField(max_length=1000)\n tags = GenericRelation(TaggedItem) We could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized. class TaggedObjectRelatedField(serializers.RelatedField):\n \"\"\"\n A custom field to use for the `tagged_object` generic relationship.\n \"\"\"\n\n def to_representation(self, value):\n \"\"\"\n Serialize tagged objects to a simple textual representation.\n \"\"\"\n if isinstance(value, Bookmark):\n return 'Bookmark: ' + value.url\n elif isinstance(value, Note):\n return 'Note: ' + value.text\n raise Exception('Unexpected type of tagged object') If you need the target of the relationship to have a nested representation, you can use the required serializers inside the .to_representation() method: def to_representation(self, value):\n \"\"\"\n Serialize bookmark instances using a bookmark serializer,\n and note instances using a note serializer.\n \"\"\"\n if isinstance(value, Bookmark):\n serializer = BookmarkSerializer(value)\n elif isinstance(value, Note):\n serializer = NoteSerializer(value)\n else:\n raise Exception('Unexpected type of tagged object')\n\n return serializer.data Note that reverse generic keys, expressed using the GenericRelation field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known. For more information see the Django documentation on generic relations .", + "text": "If you want to serialize a generic foreign key, you need to define a custom field, to determine explicitly how you want to serialize the targets of the relationship. For example, given the following model for a tag, which has a generic relationship with other arbitrary models: class TaggedItem(models.Model):\n \"\"\"\n Tags arbitrary model instances using a generic relation.\n\n See: https://docs.djangoproject.com/en/stable/ref/contrib/contenttypes/\n \"\"\"\n tag_name = models.SlugField()\n content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)\n object_id = models.PositiveIntegerField()\n tagged_object = GenericForeignKey('content_type', 'object_id')\n\n def __unicode__(self):\n return self.tag_name And the following two models, which may have associated tags: class Bookmark(models.Model):\n \"\"\"\n A bookmark consists of a URL, and 0 or more descriptive tags.\n \"\"\"\n url = models.URLField()\n tags = GenericRelation(TaggedItem)\n\n\nclass Note(models.Model):\n \"\"\"\n A note consists of some text, and 0 or more descriptive tags.\n \"\"\"\n text = models.CharField(max_length=1000)\n tags = GenericRelation(TaggedItem) We could define a custom field that could be used to serialize tagged instances, using the type of each instance to determine how it should be serialized. class TaggedObjectRelatedField(serializers.RelatedField):\n \"\"\"\n A custom field to use for the `tagged_object` generic relationship.\n \"\"\"\n\n def to_representation(self, value):\n \"\"\"\n Serialize tagged objects to a simple textual representation.\n \"\"\"\n if isinstance(value, Bookmark):\n return 'Bookmark: ' + value.url\n elif isinstance(value, Note):\n return 'Note: ' + value.text\n raise Exception('Unexpected type of tagged object') If you need the target of the relationship to have a nested representation, you can use the required serializers inside the .to_representation() method: def to_representation(self, value):\n \"\"\"\n Serialize bookmark instances using a bookmark serializer,\n and note instances using a note serializer.\n \"\"\"\n if isinstance(value, Bookmark):\n serializer = BookmarkSerializer(value)\n elif isinstance(value, Note):\n serializer = NoteSerializer(value)\n else:\n raise Exception('Unexpected type of tagged object')\n\n return serializer.data Note that reverse generic keys, expressed using the GenericRelation field, can be serialized using the regular relational field types, since the type of the target in the relationship is always known. For more information see the Django documentation on generic relations .", "title": "Generic relationships" }, { @@ -2167,7 +2167,7 @@ }, { "location": "/api-guide/validators/", - "text": "Validators\n\n\n\n\nValidators can be useful for re-using validation logic between different types of fields.\n\n\n \nDjango documentation\n\n\n\n\nMost of the time you're dealing with validation in REST framework you'll simply be relying on the default field validation, or writing explicit validation methods on serializer or field classes.\n\n\nHowever, sometimes you'll want to place your validation logic into reusable components, so that it can easily be reused throughout your codebase. This can be achieved by using validator functions and validator classes.\n\n\nValidation in REST framework\n\n\nValidation in Django REST framework serializers is handled a little differently to how validation works in Django's \nModelForm\n class.\n\n\nWith \nModelForm\n the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons:\n\n\n\n\nIt introduces a proper separation of concerns, making your code behavior more obvious.\n\n\nIt is easy to switch between using shortcut \nModelSerializer\n classes and using explicit \nSerializer\n classes. Any validation behavior being used for \nModelSerializer\n is simple to replicate.\n\n\nPrinting the \nrepr\n of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behavior being called on the model instance.\n\n\n\n\nWhen you're using \nModelSerializer\n all of this is handled automatically for you. If you want to drop down to using a \nSerializer\n classes instead, then you need to define the validation rules explicitly.\n\n\nExample\n\n\nAs an example of how REST framework uses explicit validation, we'll take a simple model class that has a field with a uniqueness constraint.\n\n\nclass CustomerReportRecord(models.Model):\n time_raised = models.DateTimeField(default=timezone.now, editable=False)\n reference = models.CharField(unique=True, max_length=20)\n description = models.TextField()\n\n\n\nHere's a basic \nModelSerializer\n that we can use for creating or updating instances of \nCustomerReportRecord\n:\n\n\nclass CustomerReportSerializer(serializers.ModelSerializer):\n class Meta:\n model = CustomerReportRecord\n\n\n\nIf we open up the Django shell using \nmanage.py shell\n we can now\n\n\n from project.example.serializers import CustomerReportSerializer\n\n serializer = CustomerReportSerializer()\n\n print(repr(serializer))\nCustomerReportSerializer():\n id = IntegerField(label='ID', read_only=True)\n time_raised = DateTimeField(read_only=True)\n reference = CharField(max_length=20, validators=[\nUniqueValidator(queryset=CustomerReportRecord.objects.all())\n])\n description = CharField(style={'type': 'textarea'})\n\n\n\nThe interesting bit here is the \nreference\n field. We can see that the uniqueness constraint is being explicitly enforced by a validator on the serializer field.\n\n\nBecause of this more explicit style REST framework includes a few validator classes that are not available in core Django. These classes are detailed below.\n\n\n\n\nUniqueValidator\n\n\nThis validator can be used to enforce the \nunique=True\n constraint on model fields.\nIt takes a single required argument, and an optional \nmessages\n argument:\n\n\n\n\nqueryset\n \nrequired\n - This is the queryset against which uniqueness should be enforced.\n\n\nmessage\n - The error message that should be used when validation fails.\n\n\nlookup\n - The lookup used to find an existing instance with the value being validated. Defaults to \n'exact'\n.\n\n\n\n\nThis validator should be applied to \nserializer fields\n, like so:\n\n\nfrom rest_framework.validators import UniqueValidator\n\nslug = SlugField(\n max_length=100,\n validators=[UniqueValidator(queryset=BlogPost.objects.all())]\n)\n\n\n\nUniqueTogetherValidator\n\n\nThis validator can be used to enforce \nunique_together\n constraints on model instances.\nIt has two required arguments, and a single optional \nmessages\n argument:\n\n\n\n\nqueryset\n \nrequired\n - This is the queryset against which uniqueness should be enforced.\n\n\nfields\n \nrequired\n - A list or tuple of field names which should make a unique set. These must exist as fields on the serializer class.\n\n\nmessage\n - The error message that should be used when validation fails.\n\n\n\n\nThe validator should be applied to \nserializer classes\n, like so:\n\n\nfrom rest_framework.validators import UniqueTogetherValidator\n\nclass ExampleSerializer(serializers.Serializer):\n # ...\n class Meta:\n # ToDo items belong to a parent list, and have an ordering defined\n #\u00a0by the 'position' field. No two items in a given list may share\n # the same position.\n validators = [\n UniqueTogetherValidator(\n queryset=ToDoItem.objects.all(),\n fields=('list', 'position')\n )\n ]\n\n\n\n\n\nNote\n: The \nUniqueTogetherValidation\n class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with \ndefault\n values are an exception to this as they always supply a value even when omitted from user input.\n\n\n\n\nUniqueForDateValidator\n\n\nUniqueForMonthValidator\n\n\nUniqueForYearValidator\n\n\nThese validators can be used to enforce the \nunique_for_date\n, \nunique_for_month\n and \nunique_for_year\n constraints on model instances. They take the following arguments:\n\n\n\n\nqueryset\n \nrequired\n - This is the queryset against which uniqueness should be enforced.\n\n\nfield\n \nrequired\n - A field name against which uniqueness in the given date range will be validated. This must exist as a field on the serializer class.\n\n\ndate_field\n \nrequired\n - A field name which will be used to determine date range for the uniqueness constrain. This must exist as a field on the serializer class.\n\n\nmessage\n - The error message that should be used when validation fails.\n\n\n\n\nThe validator should be applied to \nserializer classes\n, like so:\n\n\nfrom rest_framework.validators import UniqueForYearValidator\n\nclass ExampleSerializer(serializers.Serializer):\n # ...\n class Meta:\n # Blog posts should have a slug that is unique for the current year.\n validators = [\n UniqueForYearValidator(\n queryset=BlogPostItem.objects.all(),\n field='slug',\n date_field='published'\n )\n ]\n\n\n\nThe date field that is used for the validation is always required to be present on the serializer class. You can't simply rely on a model class \ndefault=...\n, because the value being used for the default wouldn't be generated until after the validation has run.\n\n\nThere are a couple of styles you may want to use for this depending on how you want your API to behave. If you're using \nModelSerializer\n you'll probably simply rely on the defaults that REST framework generates for you, but if you are using \nSerializer\n or simply want more explicit control, use on of the styles demonstrated below.\n\n\nUsing with a writable date field.\n\n\nIf you want the date field to be writable the only thing worth noting is that you should ensure that it is always available in the input data, either by setting a \ndefault\n argument, or by setting \nrequired=True\n.\n\n\npublished = serializers.DateTimeField(required=True)\n\n\n\nUsing with a read-only date field.\n\n\nIf you want the date field to be visible, but not editable by the user, then set \nread_only=True\n and additionally set a \ndefault=...\n argument.\n\n\npublished = serializers.DateTimeField(read_only=True, default=timezone.now)\n\n\n\nThe field will not be writable to the user, but the default value will still be passed through to the \nvalidated_data\n.\n\n\nUsing with a hidden date field.\n\n\nIf you want the date field to be entirely hidden from the user, then use \nHiddenField\n. This field type does not accept user input, but instead always returns it's default value to the \nvalidated_data\n in the serializer.\n\n\npublished = serializers.HiddenField(default=timezone.now)\n\n\n\n\n\nNote\n: The \nUniqueFor\nRange\nValidation\n classes always imposes an implicit constraint that the fields they are applied to are always treated as required. Fields with \ndefault\n values are an exception to this as they always supply a value even when omitted from user input.\n\n\n\n\nAdvanced field defaults\n\n\nValidators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that \nis\n available as input to the validator.\n\n\nTwo patterns that you may want to use for this sort of validation include:\n\n\n\n\nUsing \nHiddenField\n. This field will be present in \nvalidated_data\n but \nwill not\n be used in the serializer output representation.\n\n\nUsing a standard field with \nread_only=True\n, but that also includes a \ndefault=\u2026\n argument. This field \nwill\n be used in the serializer output representation, but cannot be set directly by the user.\n\n\n\n\nREST framework includes a couple of defaults that may be useful in this context.\n\n\nCurrentUserDefault\n\n\nA default class that can be used to represent the current user. In order to use this, the 'request' must have been provided as part of the context dictionary when instantiating the serializer.\n\n\nowner = serializers.HiddenField(\n default=serializers.CurrentUserDefault()\n)\n\n\n\nCreateOnlyDefault\n\n\nA default class that can be used to \nonly set a default argument during create operations\n. During updates the field is omitted.\n\n\nIt takes a single argument, which is the default value or callable that should be used during create operations.\n\n\ncreated_at = serializers.DateTimeField(\n read_only=True,\n default=serializers.CreateOnlyDefault(timezone.now)\n)\n\n\n\n\n\nLimitations of validators\n\n\nThere are some ambiguous cases where you'll need to instead handle validation\nexplicitly, rather than relying on the default serializer classes that\n\nModelSerializer\n generates.\n\n\nIn these cases you may want to disable the automatically generated validators,\nby specifying an empty list for the serializer \nMeta.validators\n attribute.\n\n\nOptional fields\n\n\nBy default \"unique together\" validation enforces that all fields be\n\nrequired=True\n. In some cases, you might want to explicit apply\n\nrequired=False\n to one of the fields, in which case the desired behaviour\nof the validation is ambiguous.\n\n\nIn this case you will typically need to exclude the validator from the\nserializer class, and instead write any validation logic explicitly, either\nin the \n.validate()\n method, or else in the view.\n\n\nFor example:\n\n\nclass BillingRecordSerializer(serializers.ModelSerializer):\n def validate(self, data):\n # Apply custom validation either here, or in the view.\n\n class Meta:\n fields = ('client', 'date', 'amount')\n extra_kwargs = {'client': {'required': 'False'}}\n validators = [] # Remove a default \"unique together\" constraint.\n\n\n\nUpdating nested serializers\n\n\nWhen applying an update to an existing instance, uniqueness validators will\nexclude the current instance from the uniqueness check. The current instance\nis available in the context of the uniqueness check, because it exists as\nan attribute on the serializer, having initially been passed using\n\ninstance=...\n when instantiating the serializer.\n\n\nIn the case of update operations on \nnested\n serializers there's no way of\napplying this exclusion, because the instance is not available.\n\n\nAgain, you'll probably want to explicitly remove the validator from the\nserializer class, and write the code the for the validation constraint\nexplicitly, in a \n.validate()\n method, or in the view.\n\n\nDebugging complex cases\n\n\nIf you're not sure exactly what behavior a \nModelSerializer\n class will\ngenerate it is usually a good idea to run \nmanage.py shell\n, and print\nan instance of the serializer, so that you can inspect the fields and\nvalidators that it automatically generates for you.\n\n\n serializer = MyComplexModelSerializer()\n\n print(serializer)\nclass MyComplexModelSerializer:\n my_fields = ...\n\n\n\nAlso keep in mind that with complex cases it can often be better to explicitly\ndefine your serializer classes, rather than relying on the default\n\nModelSerializer\n behavior. This involves a little more code, but ensures\nthat the resulting behavior is more transparent.\n\n\n\n\nWriting custom validators\n\n\nYou can use any of Django's existing validators, or write your own custom validators.\n\n\nFunction based\n\n\nA validator may be any callable that raises a \nserializers.ValidationError\n on failure.\n\n\ndef even_number(value):\n if value % 2 != 0:\n raise serializers.ValidationError('This field must be an even number.')\n\n\n\nField-level validation\n\n\nYou can specify custom field-level validation by adding \n.validate_\nfield_name\n methods\nto your \nSerializer\n subclass. This is documented in the\n\nSerializer docs\n\n\nClass-based\n\n\nTo write a class-based validator, use the \n__call__\n method. Class-based validators are useful as they allow you to parameterize and reuse behavior.\n\n\nclass MultipleOf(object):\n def __init__(self, base):\n self.base = base\n\n def __call__(self, value):\n if value % self.base != 0:\n message = 'This field must be a multiple of %d.' % self.base\n raise serializers.ValidationError(message)\n\n\n\nUsing \nset_context()\n\n\nIn some advanced cases you might want a validator to be passed the serializer field it is being used with as additional context. You can do so by declaring a \nset_context\n method on a class-based validator.\n\n\ndef set_context(self, serializer_field):\n # Determine if this is an update or a create operation.\n # In `__call__` we can then use that information to modify the validation behavior.\n self.is_update = serializer_field.parent.instance is not None", + "text": "Validators\n\n\n\n\nValidators can be useful for re-using validation logic between different types of fields.\n\n\n \nDjango documentation\n\n\n\n\nMost of the time you're dealing with validation in REST framework you'll simply be relying on the default field validation, or writing explicit validation methods on serializer or field classes.\n\n\nHowever, sometimes you'll want to place your validation logic into reusable components, so that it can easily be reused throughout your codebase. This can be achieved by using validator functions and validator classes.\n\n\nValidation in REST framework\n\n\nValidation in Django REST framework serializers is handled a little differently to how validation works in Django's \nModelForm\n class.\n\n\nWith \nModelForm\n the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons:\n\n\n\n\nIt introduces a proper separation of concerns, making your code behavior more obvious.\n\n\nIt is easy to switch between using shortcut \nModelSerializer\n classes and using explicit \nSerializer\n classes. Any validation behavior being used for \nModelSerializer\n is simple to replicate.\n\n\nPrinting the \nrepr\n of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behavior being called on the model instance.\n\n\n\n\nWhen you're using \nModelSerializer\n all of this is handled automatically for you. If you want to drop down to using \nSerializer\n classes instead, then you need to define the validation rules explicitly.\n\n\nExample\n\n\nAs an example of how REST framework uses explicit validation, we'll take a simple model class that has a field with a uniqueness constraint.\n\n\nclass CustomerReportRecord(models.Model):\n time_raised = models.DateTimeField(default=timezone.now, editable=False)\n reference = models.CharField(unique=True, max_length=20)\n description = models.TextField()\n\n\n\nHere's a basic \nModelSerializer\n that we can use for creating or updating instances of \nCustomerReportRecord\n:\n\n\nclass CustomerReportSerializer(serializers.ModelSerializer):\n class Meta:\n model = CustomerReportRecord\n\n\n\nIf we open up the Django shell using \nmanage.py shell\n we can now\n\n\n from project.example.serializers import CustomerReportSerializer\n\n serializer = CustomerReportSerializer()\n\n print(repr(serializer))\nCustomerReportSerializer():\n id = IntegerField(label='ID', read_only=True)\n time_raised = DateTimeField(read_only=True)\n reference = CharField(max_length=20, validators=[\nUniqueValidator(queryset=CustomerReportRecord.objects.all())\n])\n description = CharField(style={'type': 'textarea'})\n\n\n\nThe interesting bit here is the \nreference\n field. We can see that the uniqueness constraint is being explicitly enforced by a validator on the serializer field.\n\n\nBecause of this more explicit style REST framework includes a few validator classes that are not available in core Django. These classes are detailed below.\n\n\n\n\nUniqueValidator\n\n\nThis validator can be used to enforce the \nunique=True\n constraint on model fields.\nIt takes a single required argument, and an optional \nmessages\n argument:\n\n\n\n\nqueryset\n \nrequired\n - This is the queryset against which uniqueness should be enforced.\n\n\nmessage\n - The error message that should be used when validation fails.\n\n\nlookup\n - The lookup used to find an existing instance with the value being validated. Defaults to \n'exact'\n.\n\n\n\n\nThis validator should be applied to \nserializer fields\n, like so:\n\n\nfrom rest_framework.validators import UniqueValidator\n\nslug = SlugField(\n max_length=100,\n validators=[UniqueValidator(queryset=BlogPost.objects.all())]\n)\n\n\n\nUniqueTogetherValidator\n\n\nThis validator can be used to enforce \nunique_together\n constraints on model instances.\nIt has two required arguments, and a single optional \nmessages\n argument:\n\n\n\n\nqueryset\n \nrequired\n - This is the queryset against which uniqueness should be enforced.\n\n\nfields\n \nrequired\n - A list or tuple of field names which should make a unique set. These must exist as fields on the serializer class.\n\n\nmessage\n - The error message that should be used when validation fails.\n\n\n\n\nThe validator should be applied to \nserializer classes\n, like so:\n\n\nfrom rest_framework.validators import UniqueTogetherValidator\n\nclass ExampleSerializer(serializers.Serializer):\n # ...\n class Meta:\n # ToDo items belong to a parent list, and have an ordering defined\n #\u00a0by the 'position' field. No two items in a given list may share\n # the same position.\n validators = [\n UniqueTogetherValidator(\n queryset=ToDoItem.objects.all(),\n fields=('list', 'position')\n )\n ]\n\n\n\n\n\nNote\n: The \nUniqueTogetherValidation\n class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with \ndefault\n values are an exception to this as they always supply a value even when omitted from user input.\n\n\n\n\nUniqueForDateValidator\n\n\nUniqueForMonthValidator\n\n\nUniqueForYearValidator\n\n\nThese validators can be used to enforce the \nunique_for_date\n, \nunique_for_month\n and \nunique_for_year\n constraints on model instances. They take the following arguments:\n\n\n\n\nqueryset\n \nrequired\n - This is the queryset against which uniqueness should be enforced.\n\n\nfield\n \nrequired\n - A field name against which uniqueness in the given date range will be validated. This must exist as a field on the serializer class.\n\n\ndate_field\n \nrequired\n - A field name which will be used to determine date range for the uniqueness constrain. This must exist as a field on the serializer class.\n\n\nmessage\n - The error message that should be used when validation fails.\n\n\n\n\nThe validator should be applied to \nserializer classes\n, like so:\n\n\nfrom rest_framework.validators import UniqueForYearValidator\n\nclass ExampleSerializer(serializers.Serializer):\n # ...\n class Meta:\n # Blog posts should have a slug that is unique for the current year.\n validators = [\n UniqueForYearValidator(\n queryset=BlogPostItem.objects.all(),\n field='slug',\n date_field='published'\n )\n ]\n\n\n\nThe date field that is used for the validation is always required to be present on the serializer class. You can't simply rely on a model class \ndefault=...\n, because the value being used for the default wouldn't be generated until after the validation has run.\n\n\nThere are a couple of styles you may want to use for this depending on how you want your API to behave. If you're using \nModelSerializer\n you'll probably simply rely on the defaults that REST framework generates for you, but if you are using \nSerializer\n or simply want more explicit control, use on of the styles demonstrated below.\n\n\nUsing with a writable date field.\n\n\nIf you want the date field to be writable the only thing worth noting is that you should ensure that it is always available in the input data, either by setting a \ndefault\n argument, or by setting \nrequired=True\n.\n\n\npublished = serializers.DateTimeField(required=True)\n\n\n\nUsing with a read-only date field.\n\n\nIf you want the date field to be visible, but not editable by the user, then set \nread_only=True\n and additionally set a \ndefault=...\n argument.\n\n\npublished = serializers.DateTimeField(read_only=True, default=timezone.now)\n\n\n\nThe field will not be writable to the user, but the default value will still be passed through to the \nvalidated_data\n.\n\n\nUsing with a hidden date field.\n\n\nIf you want the date field to be entirely hidden from the user, then use \nHiddenField\n. This field type does not accept user input, but instead always returns its default value to the \nvalidated_data\n in the serializer.\n\n\npublished = serializers.HiddenField(default=timezone.now)\n\n\n\n\n\nNote\n: The \nUniqueFor\nRange\nValidation\n classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with \ndefault\n values are an exception to this as they always supply a value even when omitted from user input.\n\n\n\n\nAdvanced field defaults\n\n\nValidators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that \nis\n available as input to the validator.\n\n\nTwo patterns that you may want to use for this sort of validation include:\n\n\n\n\nUsing \nHiddenField\n. This field will be present in \nvalidated_data\n but \nwill not\n be used in the serializer output representation.\n\n\nUsing a standard field with \nread_only=True\n, but that also includes a \ndefault=\u2026\n argument. This field \nwill\n be used in the serializer output representation, but cannot be set directly by the user.\n\n\n\n\nREST framework includes a couple of defaults that may be useful in this context.\n\n\nCurrentUserDefault\n\n\nA default class that can be used to represent the current user. In order to use this, the 'request' must have been provided as part of the context dictionary when instantiating the serializer.\n\n\nowner = serializers.HiddenField(\n default=serializers.CurrentUserDefault()\n)\n\n\n\nCreateOnlyDefault\n\n\nA default class that can be used to \nonly set a default argument during create operations\n. During updates the field is omitted.\n\n\nIt takes a single argument, which is the default value or callable that should be used during create operations.\n\n\ncreated_at = serializers.DateTimeField(\n read_only=True,\n default=serializers.CreateOnlyDefault(timezone.now)\n)\n\n\n\n\n\nLimitations of validators\n\n\nThere are some ambiguous cases where you'll need to instead handle validation\nexplicitly, rather than relying on the default serializer classes that\n\nModelSerializer\n generates.\n\n\nIn these cases you may want to disable the automatically generated validators,\nby specifying an empty list for the serializer \nMeta.validators\n attribute.\n\n\nOptional fields\n\n\nBy default \"unique together\" validation enforces that all fields be\n\nrequired=True\n. In some cases, you might want to explicit apply\n\nrequired=False\n to one of the fields, in which case the desired behaviour\nof the validation is ambiguous.\n\n\nIn this case you will typically need to exclude the validator from the\nserializer class, and instead write any validation logic explicitly, either\nin the \n.validate()\n method, or else in the view.\n\n\nFor example:\n\n\nclass BillingRecordSerializer(serializers.ModelSerializer):\n def validate(self, data):\n # Apply custom validation either here, or in the view.\n\n class Meta:\n fields = ('client', 'date', 'amount')\n extra_kwargs = {'client': {'required': 'False'}}\n validators = [] # Remove a default \"unique together\" constraint.\n\n\n\nUpdating nested serializers\n\n\nWhen applying an update to an existing instance, uniqueness validators will\nexclude the current instance from the uniqueness check. The current instance\nis available in the context of the uniqueness check, because it exists as\nan attribute on the serializer, having initially been passed using\n\ninstance=...\n when instantiating the serializer.\n\n\nIn the case of update operations on \nnested\n serializers there's no way of\napplying this exclusion, because the instance is not available.\n\n\nAgain, you'll probably want to explicitly remove the validator from the\nserializer class, and write the code the for the validation constraint\nexplicitly, in a \n.validate()\n method, or in the view.\n\n\nDebugging complex cases\n\n\nIf you're not sure exactly what behavior a \nModelSerializer\n class will\ngenerate it is usually a good idea to run \nmanage.py shell\n, and print\nan instance of the serializer, so that you can inspect the fields and\nvalidators that it automatically generates for you.\n\n\n serializer = MyComplexModelSerializer()\n\n print(serializer)\nclass MyComplexModelSerializer:\n my_fields = ...\n\n\n\nAlso keep in mind that with complex cases it can often be better to explicitly\ndefine your serializer classes, rather than relying on the default\n\nModelSerializer\n behavior. This involves a little more code, but ensures\nthat the resulting behavior is more transparent.\n\n\n\n\nWriting custom validators\n\n\nYou can use any of Django's existing validators, or write your own custom validators.\n\n\nFunction based\n\n\nA validator may be any callable that raises a \nserializers.ValidationError\n on failure.\n\n\ndef even_number(value):\n if value % 2 != 0:\n raise serializers.ValidationError('This field must be an even number.')\n\n\n\nField-level validation\n\n\nYou can specify custom field-level validation by adding \n.validate_\nfield_name\n methods\nto your \nSerializer\n subclass. This is documented in the\n\nSerializer docs\n\n\nClass-based\n\n\nTo write a class-based validator, use the \n__call__\n method. Class-based validators are useful as they allow you to parameterize and reuse behavior.\n\n\nclass MultipleOf(object):\n def __init__(self, base):\n self.base = base\n\n def __call__(self, value):\n if value % self.base != 0:\n message = 'This field must be a multiple of %d.' % self.base\n raise serializers.ValidationError(message)\n\n\n\nUsing \nset_context()\n\n\nIn some advanced cases you might want a validator to be passed the serializer field it is being used with as additional context. You can do so by declaring a \nset_context\n method on a class-based validator.\n\n\ndef set_context(self, serializer_field):\n # Determine if this is an update or a create operation.\n # In `__call__` we can then use that information to modify the validation behavior.\n self.is_update = serializer_field.parent.instance is not None", "title": "Validators" }, { @@ -2177,7 +2177,7 @@ }, { "location": "/api-guide/validators/#validation-in-rest-framework", - "text": "Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class. With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons: It introduces a proper separation of concerns, making your code behavior more obvious. It is easy to switch between using shortcut ModelSerializer classes and using explicit Serializer classes. Any validation behavior being used for ModelSerializer is simple to replicate. Printing the repr of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behavior being called on the model instance. When you're using ModelSerializer all of this is handled automatically for you. If you want to drop down to using a Serializer classes instead, then you need to define the validation rules explicitly.", + "text": "Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class. With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class. This is advantageous for the following reasons: It introduces a proper separation of concerns, making your code behavior more obvious. It is easy to switch between using shortcut ModelSerializer classes and using explicit Serializer classes. Any validation behavior being used for ModelSerializer is simple to replicate. Printing the repr of a serializer instance will show you exactly what validation rules it applies. There's no extra hidden validation behavior being called on the model instance. When you're using ModelSerializer all of this is handled automatically for you. If you want to drop down to using Serializer classes instead, then you need to define the validation rules explicitly.", "title": "Validation in REST framework" }, { @@ -2222,7 +2222,7 @@ }, { "location": "/api-guide/validators/#using-with-a-hidden-date-field", - "text": "If you want the date field to be entirely hidden from the user, then use HiddenField . This field type does not accept user input, but instead always returns it's default value to the validated_data in the serializer. published = serializers.HiddenField(default=timezone.now) Note : The UniqueFor Range Validation classes always imposes an implicit constraint that the fields they are applied to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.", + "text": "If you want the date field to be entirely hidden from the user, then use HiddenField . This field type does not accept user input, but instead always returns its default value to the validated_data in the serializer. published = serializers.HiddenField(default=timezone.now) Note : The UniqueFor Range Validation classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with default values are an exception to this as they always supply a value even when omitted from user input.", "title": "Using with a hidden date field." }, { @@ -2437,7 +2437,7 @@ }, { "location": "/api-guide/permissions/", - "text": "Permissions\n\n\n\n\nAuthentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization.\n\n\n \nApple Developer Documentation\n\n\n\n\nTogether with \nauthentication\n and \nthrottling\n, permissions determine whether a request should be granted or denied access.\n\n\nPermission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the \nrequest.user\n and \nrequest.auth\n properties to determine if the incoming request should be permitted.\n\n\nPermissions are used to grant or deny access different classes of users to different parts of the API.\n\n\nThe simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds the \nIsAuthenticated\n class in REST framework.\n\n\nA slightly less strict style of permission would be to allow full access to authenticated users, but allow read-only access to unauthenticated users. This corresponds to the \nIsAuthenticatedOrReadOnly\n class in REST framework.\n\n\nHow permissions are determined\n\n\nPermissions in REST framework are always defined as a list of permission classes.\n\n\nBefore running the main body of the view each permission in the list is checked.\nIf any permission check fails an \nexceptions.PermissionDenied\n or \nexceptions.NotAuthenticated\n exception will be raised, and the main body of the view will not run.\n\n\nWhen the permissions checks fail either a \"403 Forbidden\" or a \"401 Unauthorized\" response will be returned, according to the following rules:\n\n\n\n\nThe request was successfully authenticated, but permission was denied. \n An HTTP 403 Forbidden response will be returned.\n\n\nThe request was not successfully authenticated, and the highest priority authentication class \ndoes not\n use \nWWW-Authenticate\n headers. \n An HTTP 403 Forbidden response will be returned.\n\n\nThe request was not successfully authenticated, and the highest priority authentication class \ndoes\n use \nWWW-Authenticate\n headers. \n An HTTP 401 Unauthorized response, with an appropriate \nWWW-Authenticate\n header will be returned.\n\n\n\n\nObject level permissions\n\n\nREST framework permissions also support object-level permissioning. Object level permissions are used to determine if a user should be allowed to act on a particular object, which will typically be a model instance.\n\n\nObject level permissions are run by REST framework's generic views when \n.get_object()\n is called.\nAs with view level permissions, an \nexceptions.PermissionDenied\n exception will be raised if the user is not allowed to act on the given object.\n\n\nIf you're writing your own views and want to enforce object level permissions,\nor if you override the \nget_object\n method on a generic view, then you'll need to explicitly call the \n.check_object_permissions(request, obj)\n method on the view at the point at which you've retrieved the object.\n\n\nThis will either raise a \nPermissionDenied\n or \nNotAuthenticated\n exception, or simply return if the view has the appropriate permissions.\n\n\nFor example:\n\n\ndef get_object(self):\n obj = get_object_or_404(self.get_queryset())\n self.check_object_permissions(self.request, obj)\n return obj\n\n\n\nLimitations of object level permissions\n\n\nFor performance reasons the generic views will not automatically apply object level permissions to each instance in a queryset when returning a list of objects.\n\n\nOften when you're using object level permissions you'll also want to \nfilter the queryset\n appropriately, to ensure that users only have visibility onto instances that they are permitted to view.\n\n\nSetting the permission policy\n\n\nThe default permission policy may be set globally, using the \nDEFAULT_PERMISSION_CLASSES\n setting. For example.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_PERMISSION_CLASSES': (\n 'rest_framework.permissions.IsAuthenticated',\n )\n}\n\n\n\nIf not specified, this setting defaults to allowing unrestricted access:\n\n\n'DEFAULT_PERMISSION_CLASSES': (\n 'rest_framework.permissions.AllowAny',\n)\n\n\n\nYou can also set the authentication policy on a per-view, or per-viewset basis,\nusing the \nAPIView\n class-based views.\n\n\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.response import Response\nfrom rest_framework.views import APIView\n\nclass ExampleView(APIView):\n permission_classes = (IsAuthenticated,)\n\n def get(self, request, format=None):\n content = {\n 'status': 'request was permitted'\n }\n return Response(content)\n\n\n\nOr, if you're using the \n@api_view\n decorator with function based views.\n\n\nfrom rest_framework.decorators import api_view, permission_classes\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.response import Response\n\n@api_view(['GET'])\n@permission_classes((IsAuthenticated, ))\ndef example_view(request, format=None):\n content = {\n 'status': 'request was permitted'\n }\n return Response(content)\n\n\n\nNote:\n when you set new permission classes through class attribute or decorators you're telling the view to ignore the default list set over the \nsettings.py\n file.\n\n\n\n\nAPI Reference\n\n\nAllowAny\n\n\nThe \nAllowAny\n permission class will allow unrestricted access, \nregardless of if the request was authenticated or unauthenticated\n.\n\n\nThis permission is not strictly required, since you can achieve the same result by using an empty list or tuple for the permissions setting, but you may find it useful to specify this class because it makes the intention explicit.\n\n\nIsAuthenticated\n\n\nThe \nIsAuthenticated\n permission class will deny permission to any unauthenticated user, and allow permission otherwise.\n\n\nThis permission is suitable if you want your API to only be accessible to registered users.\n\n\nIsAdminUser\n\n\nThe \nIsAdminUser\n permission class will deny permission to any user, unless \nuser.is_staff\n is \nTrue\n in which case permission will be allowed.\n\n\nThis permission is suitable if you want your API to only be accessible to a subset of trusted administrators.\n\n\nIsAuthenticatedOrReadOnly\n\n\nThe \nIsAuthenticatedOrReadOnly\n will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the \"safe\" methods; \nGET\n, \nHEAD\n or \nOPTIONS\n.\n\n\nThis permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users.\n\n\nDjangoModelPermissions\n\n\nThis permission class ties into Django's standard \ndjango.contrib.auth\n \nmodel permissions\n. This permission must only be applied to views that have a \n.queryset\n property set. Authorization will only be granted if the user \nis authenticated\n and has the \nrelevant model permissions\n assigned.\n\n\n\n\nPOST\n requests require the user to have the \nadd\n permission on the model.\n\n\nPUT\n and \nPATCH\n requests require the user to have the \nchange\n permission on the model.\n\n\nDELETE\n requests require the user to have the \ndelete\n permission on the model.\n\n\n\n\nThe default behaviour can also be overridden to support custom model permissions. For example, you might want to include a \nview\n model permission for \nGET\n requests.\n\n\nTo use custom model permissions, override \nDjangoModelPermissions\n and set the \n.perms_map\n property. Refer to the source code for details.\n\n\nUsing with views that do not include a \nqueryset\n attribute.\n\n\nIf you're using this permission with a view that uses an overridden \nget_queryset()\n method there may not be a \nqueryset\n attribute on the view. In this case we suggest also marking the view with a sentinel queryset, so that this class can determine the required permissions. For example:\n\n\nqueryset = User.objects.none() # Required for DjangoModelPermissions\n\n\n\nDjangoModelPermissionsOrAnonReadOnly\n\n\nSimilar to \nDjangoModelPermissions\n, but also allows unauthenticated users to have read-only access to the API.\n\n\nDjangoObjectPermissions\n\n\nThis permission class ties into Django's standard \nobject permissions framework\n that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as \ndjango-guardian\n.\n\n\nAs with \nDjangoModelPermissions\n, this permission must only be applied to views that have a \n.queryset\n property or \n.get_queryset()\n method. Authorization will only be granted if the user \nis authenticated\n and has the \nrelevant per-object permissions\n and \nrelevant model permissions\n assigned.\n\n\n\n\nPOST\n requests require the user to have the \nadd\n permission on the model instance.\n\n\nPUT\n and \nPATCH\n requests require the user to have the \nchange\n permission on the model instance.\n\n\nDELETE\n requests require the user to have the \ndelete\n permission on the model instance.\n\n\n\n\nNote that \nDjangoObjectPermissions\n \ndoes not\n require the \ndjango-guardian\n package, and should support other object-level backends equally well.\n\n\nAs with \nDjangoModelPermissions\n you can use custom model permissions by overriding \nDjangoModelPermissions\n and setting the \n.perms_map\n property. Refer to the source code for details.\n\n\n\n\nNote\n: If you need object level \nview\n permissions for \nGET\n, \nHEAD\n and \nOPTIONS\n requests, you'll want to consider also adding the \nDjangoObjectPermissionsFilter\n class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.\n\n\n\n\n\n\nCustom permissions\n\n\nTo implement a custom permission, override \nBasePermission\n and implement either, or both, of the following methods:\n\n\n\n\n.has_permission(self, request, view)\n\n\n.has_object_permission(self, request, view, obj)\n\n\n\n\nThe methods should return \nTrue\n if the request should be granted access, and \nFalse\n otherwise.\n\n\nIf you need to test if a request is a read operation or a write operation, you should check the request method against the constant \nSAFE_METHODS\n, which is a tuple containing \n'GET'\n, \n'OPTIONS'\n and \n'HEAD'\n. For example:\n\n\nif request.method in permissions.SAFE_METHODS:\n # Check permissions for read-only request\nelse:\n # Check permissions for write request\n\n\n\n\n\nNote\n: The instance-level \nhas_object_permission\n method will only be called if the view-level \nhas_permission\n checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call \n.check_object_permissions(request, obj)\n. If you are using the generic views then this will be handled for you by default.\n\n\n\n\nCustom permissions will raise a \nPermissionDenied\n exception if the test fails. To change the error message associated with the exception, implement a \nmessage\n attribute directly on your custom permission. Otherwise the \ndefault_detail\n attribute from \nPermissionDenied\n will be used.\n\n\nfrom rest_framework import permissions\n\nclass CustomerAccessPermission(permissions.BasePermission):\n message = 'Adding customers not allowed.'\n\n def has_permission(self, request, view):\n ...\n\n\n\nExamples\n\n\nThe following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.\n\n\nfrom rest_framework import permissions\n\nclass BlacklistPermission(permissions.BasePermission):\n \"\"\"\n Global permission check for blacklisted IPs.\n \"\"\"\n\n def has_permission(self, request, view):\n ip_addr = request.META['REMOTE_ADDR']\n blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()\n return not blacklisted\n\n\n\nAs well as global permissions, that are run against all incoming requests, you can also create object-level permissions, that are only run against operations that affect a particular object instance. For example:\n\n\nclass IsOwnerOrReadOnly(permissions.BasePermission):\n \"\"\"\n Object-level permission to only allow owners of an object to edit it.\n Assumes the model instance has an `owner` attribute.\n \"\"\"\n\n def has_object_permission(self, request, view, obj):\n # Read permissions are allowed to any request,\n # so we'll always allow GET, HEAD or OPTIONS requests.\n if request.method in permissions.SAFE_METHODS:\n return True\n\n # Instance must have an attribute named `owner`.\n return obj.owner == request.user\n\n\n\nNote that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself. You can do so by calling \nself.check_object_permissions(request, obj)\n from the view once you have the object instance. This call will raise an appropriate \nAPIException\n if any object-level permission checks fail, and will otherwise simply return.\n\n\nAlso note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the \nfiltering documentation\n for more details.\n\n\n\n\nThird party packages\n\n\nThe following third party packages are also available.\n\n\nComposed Permissions\n\n\nThe \nComposed Permissions\n package provides a simple way to define complex and multi-depth (with logic operators) permission objects, using small and reusable components.\n\n\nREST Condition\n\n\nThe \nREST Condition\n package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators.\n\n\nDRY Rest Permissions\n\n\nThe \nDRY Rest Permissions\n package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrive per user.\n\n\nDjango Rest Framework Roles\n\n\nThe \nDjango Rest Framework Roles\n package makes it easier to parameterize your API over multiple types of users.", + "text": "Permissions\n\n\n\n\nAuthentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization.\n\n\n \nApple Developer Documentation\n\n\n\n\nTogether with \nauthentication\n and \nthrottling\n, permissions determine whether a request should be granted or denied access.\n\n\nPermission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the \nrequest.user\n and \nrequest.auth\n properties to determine if the incoming request should be permitted.\n\n\nPermissions are used to grant or deny access different classes of users to different parts of the API.\n\n\nThe simplest style of permission would be to allow access to any authenticated user, and deny access to any unauthenticated user. This corresponds the \nIsAuthenticated\n class in REST framework.\n\n\nA slightly less strict style of permission would be to allow full access to authenticated users, but allow read-only access to unauthenticated users. This corresponds to the \nIsAuthenticatedOrReadOnly\n class in REST framework.\n\n\nHow permissions are determined\n\n\nPermissions in REST framework are always defined as a list of permission classes.\n\n\nBefore running the main body of the view each permission in the list is checked.\nIf any permission check fails an \nexceptions.PermissionDenied\n or \nexceptions.NotAuthenticated\n exception will be raised, and the main body of the view will not run.\n\n\nWhen the permissions checks fail either a \"403 Forbidden\" or a \"401 Unauthorized\" response will be returned, according to the following rules:\n\n\n\n\nThe request was successfully authenticated, but permission was denied. \n An HTTP 403 Forbidden response will be returned.\n\n\nThe request was not successfully authenticated, and the highest priority authentication class \ndoes not\n use \nWWW-Authenticate\n headers. \n An HTTP 403 Forbidden response will be returned.\n\n\nThe request was not successfully authenticated, and the highest priority authentication class \ndoes\n use \nWWW-Authenticate\n headers. \n An HTTP 401 Unauthorized response, with an appropriate \nWWW-Authenticate\n header will be returned.\n\n\n\n\nObject level permissions\n\n\nREST framework permissions also support object-level permissioning. Object level permissions are used to determine if a user should be allowed to act on a particular object, which will typically be a model instance.\n\n\nObject level permissions are run by REST framework's generic views when \n.get_object()\n is called.\nAs with view level permissions, an \nexceptions.PermissionDenied\n exception will be raised if the user is not allowed to act on the given object.\n\n\nIf you're writing your own views and want to enforce object level permissions,\nor if you override the \nget_object\n method on a generic view, then you'll need to explicitly call the \n.check_object_permissions(request, obj)\n method on the view at the point at which you've retrieved the object.\n\n\nThis will either raise a \nPermissionDenied\n or \nNotAuthenticated\n exception, or simply return if the view has the appropriate permissions.\n\n\nFor example:\n\n\ndef get_object(self):\n obj = get_object_or_404(self.get_queryset())\n self.check_object_permissions(self.request, obj)\n return obj\n\n\n\nLimitations of object level permissions\n\n\nFor performance reasons the generic views will not automatically apply object level permissions to each instance in a queryset when returning a list of objects.\n\n\nOften when you're using object level permissions you'll also want to \nfilter the queryset\n appropriately, to ensure that users only have visibility onto instances that they are permitted to view.\n\n\nSetting the permission policy\n\n\nThe default permission policy may be set globally, using the \nDEFAULT_PERMISSION_CLASSES\n setting. For example.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_PERMISSION_CLASSES': (\n 'rest_framework.permissions.IsAuthenticated',\n )\n}\n\n\n\nIf not specified, this setting defaults to allowing unrestricted access:\n\n\n'DEFAULT_PERMISSION_CLASSES': (\n 'rest_framework.permissions.AllowAny',\n)\n\n\n\nYou can also set the authentication policy on a per-view, or per-viewset basis,\nusing the \nAPIView\n class-based views.\n\n\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.response import Response\nfrom rest_framework.views import APIView\n\nclass ExampleView(APIView):\n permission_classes = (IsAuthenticated,)\n\n def get(self, request, format=None):\n content = {\n 'status': 'request was permitted'\n }\n return Response(content)\n\n\n\nOr, if you're using the \n@api_view\n decorator with function based views.\n\n\nfrom rest_framework.decorators import api_view, permission_classes\nfrom rest_framework.permissions import IsAuthenticated\nfrom rest_framework.response import Response\n\n@api_view(['GET'])\n@permission_classes((IsAuthenticated, ))\ndef example_view(request, format=None):\n content = {\n 'status': 'request was permitted'\n }\n return Response(content)\n\n\n\nNote:\n when you set new permission classes through class attribute or decorators you're telling the view to ignore the default list set over the \nsettings.py\n file.\n\n\n\n\nAPI Reference\n\n\nAllowAny\n\n\nThe \nAllowAny\n permission class will allow unrestricted access, \nregardless of if the request was authenticated or unauthenticated\n.\n\n\nThis permission is not strictly required, since you can achieve the same result by using an empty list or tuple for the permissions setting, but you may find it useful to specify this class because it makes the intention explicit.\n\n\nIsAuthenticated\n\n\nThe \nIsAuthenticated\n permission class will deny permission to any unauthenticated user, and allow permission otherwise.\n\n\nThis permission is suitable if you want your API to only be accessible to registered users.\n\n\nIsAdminUser\n\n\nThe \nIsAdminUser\n permission class will deny permission to any user, unless \nuser.is_staff\n is \nTrue\n in which case permission will be allowed.\n\n\nThis permission is suitable if you want your API to only be accessible to a subset of trusted administrators.\n\n\nIsAuthenticatedOrReadOnly\n\n\nThe \nIsAuthenticatedOrReadOnly\n will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the \"safe\" methods; \nGET\n, \nHEAD\n or \nOPTIONS\n.\n\n\nThis permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users.\n\n\nDjangoModelPermissions\n\n\nThis permission class ties into Django's standard \ndjango.contrib.auth\n \nmodel permissions\n. This permission must only be applied to views that have a \n.queryset\n property set. Authorization will only be granted if the user \nis authenticated\n and has the \nrelevant model permissions\n assigned.\n\n\n\n\nPOST\n requests require the user to have the \nadd\n permission on the model.\n\n\nPUT\n and \nPATCH\n requests require the user to have the \nchange\n permission on the model.\n\n\nDELETE\n requests require the user to have the \ndelete\n permission on the model.\n\n\n\n\nThe default behaviour can also be overridden to support custom model permissions. For example, you might want to include a \nview\n model permission for \nGET\n requests.\n\n\nTo use custom model permissions, override \nDjangoModelPermissions\n and set the \n.perms_map\n property. Refer to the source code for details.\n\n\nUsing with views that do not include a \nqueryset\n attribute.\n\n\nIf you're using this permission with a view that uses an overridden \nget_queryset()\n method there may not be a \nqueryset\n attribute on the view. In this case we suggest also marking the view with a sentinel queryset, so that this class can determine the required permissions. For example:\n\n\nqueryset = User.objects.none() # Required for DjangoModelPermissions\n\n\n\nDjangoModelPermissionsOrAnonReadOnly\n\n\nSimilar to \nDjangoModelPermissions\n, but also allows unauthenticated users to have read-only access to the API.\n\n\nDjangoObjectPermissions\n\n\nThis permission class ties into Django's standard \nobject permissions framework\n that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as \ndjango-guardian\n.\n\n\nAs with \nDjangoModelPermissions\n, this permission must only be applied to views that have a \n.queryset\n property or \n.get_queryset()\n method. Authorization will only be granted if the user \nis authenticated\n and has the \nrelevant per-object permissions\n and \nrelevant model permissions\n assigned.\n\n\n\n\nPOST\n requests require the user to have the \nadd\n permission on the model instance.\n\n\nPUT\n and \nPATCH\n requests require the user to have the \nchange\n permission on the model instance.\n\n\nDELETE\n requests require the user to have the \ndelete\n permission on the model instance.\n\n\n\n\nNote that \nDjangoObjectPermissions\n \ndoes not\n require the \ndjango-guardian\n package, and should support other object-level backends equally well.\n\n\nAs with \nDjangoModelPermissions\n you can use custom model permissions by overriding \nDjangoObjectPermissions\n and setting the \n.perms_map\n property. Refer to the source code for details.\n\n\n\n\nNote\n: If you need object level \nview\n permissions for \nGET\n, \nHEAD\n and \nOPTIONS\n requests, you'll want to consider also adding the \nDjangoObjectPermissionsFilter\n class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.\n\n\n\n\n\n\nCustom permissions\n\n\nTo implement a custom permission, override \nBasePermission\n and implement either, or both, of the following methods:\n\n\n\n\n.has_permission(self, request, view)\n\n\n.has_object_permission(self, request, view, obj)\n\n\n\n\nThe methods should return \nTrue\n if the request should be granted access, and \nFalse\n otherwise.\n\n\nIf you need to test if a request is a read operation or a write operation, you should check the request method against the constant \nSAFE_METHODS\n, which is a tuple containing \n'GET'\n, \n'OPTIONS'\n and \n'HEAD'\n. For example:\n\n\nif request.method in permissions.SAFE_METHODS:\n # Check permissions for read-only request\nelse:\n # Check permissions for write request\n\n\n\n\n\nNote\n: The instance-level \nhas_object_permission\n method will only be called if the view-level \nhas_permission\n checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call \n.check_object_permissions(request, obj)\n. If you are using the generic views then this will be handled for you by default.\n\n\n\n\nCustom permissions will raise a \nPermissionDenied\n exception if the test fails. To change the error message associated with the exception, implement a \nmessage\n attribute directly on your custom permission. Otherwise the \ndefault_detail\n attribute from \nPermissionDenied\n will be used.\n\n\nfrom rest_framework import permissions\n\nclass CustomerAccessPermission(permissions.BasePermission):\n message = 'Adding customers not allowed.'\n\n def has_permission(self, request, view):\n ...\n\n\n\nExamples\n\n\nThe following is an example of a permission class that checks the incoming request's IP address against a blacklist, and denies the request if the IP has been blacklisted.\n\n\nfrom rest_framework import permissions\n\nclass BlacklistPermission(permissions.BasePermission):\n \"\"\"\n Global permission check for blacklisted IPs.\n \"\"\"\n\n def has_permission(self, request, view):\n ip_addr = request.META['REMOTE_ADDR']\n blacklisted = Blacklist.objects.filter(ip_addr=ip_addr).exists()\n return not blacklisted\n\n\n\nAs well as global permissions, that are run against all incoming requests, you can also create object-level permissions, that are only run against operations that affect a particular object instance. For example:\n\n\nclass IsOwnerOrReadOnly(permissions.BasePermission):\n \"\"\"\n Object-level permission to only allow owners of an object to edit it.\n Assumes the model instance has an `owner` attribute.\n \"\"\"\n\n def has_object_permission(self, request, view, obj):\n # Read permissions are allowed to any request,\n # so we'll always allow GET, HEAD or OPTIONS requests.\n if request.method in permissions.SAFE_METHODS:\n return True\n\n # Instance must have an attribute named `owner`.\n return obj.owner == request.user\n\n\n\nNote that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself. You can do so by calling \nself.check_object_permissions(request, obj)\n from the view once you have the object instance. This call will raise an appropriate \nAPIException\n if any object-level permission checks fail, and will otherwise simply return.\n\n\nAlso note that the generic views will only check the object-level permissions for views that retrieve a single model instance. If you require object-level filtering of list views, you'll need to filter the queryset separately. See the \nfiltering documentation\n for more details.\n\n\n\n\nThird party packages\n\n\nThe following third party packages are also available.\n\n\nComposed Permissions\n\n\nThe \nComposed Permissions\n package provides a simple way to define complex and multi-depth (with logic operators) permission objects, using small and reusable components.\n\n\nREST Condition\n\n\nThe \nREST Condition\n package is another extension for building complex permissions in a simple and convenient way. The extension allows you to combine permissions with logical operators.\n\n\nDRY Rest Permissions\n\n\nThe \nDRY Rest Permissions\n package provides the ability to define different permissions for individual default and custom actions. This package is made for apps with permissions that are derived from relationships defined in the app's data model. It also supports permission checks being returned to a client app through the API's serializer. Additionally it supports adding permissions to the default and custom list actions to restrict the data they retrive per user.\n\n\nDjango Rest Framework Roles\n\n\nThe \nDjango Rest Framework Roles\n package makes it easier to parameterize your API over multiple types of users.", "title": "Permissions" }, { @@ -2507,7 +2507,7 @@ }, { "location": "/api-guide/permissions/#djangoobjectpermissions", - "text": "This permission class ties into Django's standard object permissions framework that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as django-guardian . As with DjangoModelPermissions , this permission must only be applied to views that have a .queryset property or .get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant per-object permissions and relevant model permissions assigned. POST requests require the user to have the add permission on the model instance. PUT and PATCH requests require the user to have the change permission on the model instance. DELETE requests require the user to have the delete permission on the model instance. Note that DjangoObjectPermissions does not require the django-guardian package, and should support other object-level backends equally well. As with DjangoModelPermissions you can use custom model permissions by overriding DjangoModelPermissions and setting the .perms_map property. Refer to the source code for details. Note : If you need object level view permissions for GET , HEAD and OPTIONS requests, you'll want to consider also adding the DjangoObjectPermissionsFilter class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.", + "text": "This permission class ties into Django's standard object permissions framework that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as django-guardian . As with DjangoModelPermissions , this permission must only be applied to views that have a .queryset property or .get_queryset() method. Authorization will only be granted if the user is authenticated and has the relevant per-object permissions and relevant model permissions assigned. POST requests require the user to have the add permission on the model instance. PUT and PATCH requests require the user to have the change permission on the model instance. DELETE requests require the user to have the delete permission on the model instance. Note that DjangoObjectPermissions does not require the django-guardian package, and should support other object-level backends equally well. As with DjangoModelPermissions you can use custom model permissions by overriding DjangoObjectPermissions and setting the .perms_map property. Refer to the source code for details. Note : If you need object level view permissions for GET , HEAD and OPTIONS requests, you'll want to consider also adding the DjangoObjectPermissionsFilter class to ensure that list endpoints only return results including objects for which the user has appropriate view permissions.", "title": "DjangoObjectPermissions" }, { @@ -2607,7 +2607,7 @@ }, { "location": "/api-guide/filtering/", - "text": "Filtering\n\n\n\n\nThe root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects.\n\n\n \nDjango documentation\n\n\n\n\nThe default behavior of REST framework's generic list views is to return the entire queryset for a model manager. Often you will want your API to restrict the items that are returned by the queryset.\n\n\nThe simplest way to filter the queryset of any view that subclasses \nGenericAPIView\n is to override the \n.get_queryset()\n method.\n\n\nOverriding this method allows you to customize the queryset returned by the view in a number of different ways.\n\n\nFiltering against the current user\n\n\nYou might want to filter the queryset to ensure that only results relevant to the currently authenticated user making the request are returned.\n\n\nYou can do so by filtering based on the value of \nrequest.user\n.\n\n\nFor example:\n\n\nfrom myapp.models import Purchase\nfrom myapp.serializers import PurchaseSerializer\nfrom rest_framework import generics\n\nclass PurchaseList(generics.ListAPIView):\n serializer_class = PurchaseSerializer\n\n def get_queryset(self):\n \"\"\"\n This view should return a list of all the purchases\n for the currently authenticated user.\n \"\"\"\n user = self.request.user\n return Purchase.objects.filter(purchaser=user)\n\n\n\nFiltering against the URL\n\n\nAnother style of filtering might involve restricting the queryset based on some part of the URL.\n\n\nFor example if your URL config contained an entry like this:\n\n\nurl('^purchases/(?P\nusername\n.+)/$', PurchaseList.as_view()),\n\n\n\nYou could then write a view that returned a purchase queryset filtered by the username portion of the URL:\n\n\nclass PurchaseList(generics.ListAPIView):\n serializer_class = PurchaseSerializer\n\n def get_queryset(self):\n \"\"\"\n This view should return a list of all the purchases for\n the user as determined by the username portion of the URL.\n \"\"\"\n username = self.kwargs['username']\n return Purchase.objects.filter(purchaser__username=username)\n\n\n\nFiltering against query parameters\n\n\nA final example of filtering the initial queryset would be to determine the initial queryset based on query parameters in the url.\n\n\nWe can override \n.get_queryset()\n to deal with URLs such as \nhttp://example.com/api/purchases?username=denvercoder9\n, and filter the queryset only if the \nusername\n parameter is included in the URL:\n\n\nclass PurchaseList(generics.ListAPIView):\n serializer_class = PurchaseSerializer\n\n def get_queryset(self):\n \"\"\"\n Optionally restricts the returned purchases to a given user,\n by filtering against a `username` query parameter in the URL.\n \"\"\"\n queryset = Purchase.objects.all()\n username = self.request.query_params.get('username', None)\n if username is not None:\n queryset = queryset.filter(purchaser__username=username)\n return queryset\n\n\n\n\n\nGeneric Filtering\n\n\nAs well as being able to override the default queryset, REST framework also includes support for generic filtering backends that allow you to easily construct complex searches and filters.\n\n\nGeneric filters can also present themselves as HTML controls in the browsable API and admin API.\n\n\n\n\nSetting filter backends\n\n\nThe default filter backends may be set globally, using the \nDEFAULT_FILTER_BACKENDS\n setting. For example.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)\n}\n\n\n\nYou can also set the filter backends on a per-view, or per-viewset basis,\nusing the \nGenericAPIView\n class-based views.\n\n\nimport django_filters\nfrom django.contrib.auth.models import User\nfrom myapp.serializers import UserSerializer\nfrom rest_framework import generics\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)\n\n\n\nFiltering and object lookups\n\n\nNote that if a filter backend is configured for a view, then as well as being used to filter list views, it will also be used to filter the querysets used for returning a single object.\n\n\nFor instance, given the previous example, and a product with an id of \n4675\n, the following URL would either return the corresponding object, or return a 404 response, depending on if the filtering conditions were met by the given product instance:\n\n\nhttp://example.com/api/products/4675/?category=clothing\nmax_price=10.00\n\n\n\nOverriding the initial queryset\n\n\nNote that you can use both an overridden \n.get_queryset()\n and generic filtering together, and everything will work as expected. For example, if \nProduct\n had a many-to-many relationship with \nUser\n, named \npurchase\n, you might want to write a view like this:\n\n\nclass PurchasedProductsList(generics.ListAPIView):\n \"\"\"\n Return a list of all the products that the authenticated\n user has ever purchased, with optional filtering.\n \"\"\"\n model = Product\n serializer_class = ProductSerializer\n filter_class = ProductFilter\n\n def get_queryset(self):\n user = self.request.user\n return user.purchase_set.all()\n\n\n\n\n\nAPI Guide\n\n\nDjangoFilterBackend\n\n\nThe \ndjango-filter\n library includes a \nDjangoFilterBackend\n class which\nsupports highly customizable field filtering for REST framework.\n\n\nTo use \nDjangoFilterBackend\n, first install \ndjango-filter\n.\n\n\npip install django-filter\n\n\n\nYou should now either add the filter backend to your settings:\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)\n}\n\n\n\nOr add the filter backend to an individual View or ViewSet.\n\n\nfrom django_filters.rest_framework import DjangoFilterBackend\n\nclass UserListView(generics.ListAPIView):\n ...\n filter_backends = (DjangoFilterBackend,)\n\n\n\nIf you are using the browsable API or admin API you may also want to install \ndjango-crispy-forms\n, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML.\n\n\npip install django-crispy-forms\n\n\n\nWith crispy forms installed and added to Django's \nINSTALLED_APPS\n, the browsable API will present a filtering control for \nDjangoFilterBackend\n, like so:\n\n\n\n\nSpecifying filter fields\n\n\nIf all you need is simple equality-based filtering, you can set a \nfilter_fields\n attribute on the view, or viewset, listing the set of fields you wish to filter against.\n\n\nclass ProductList(generics.ListAPIView):\n queryset = Product.objects.all()\n serializer_class = ProductSerializer\n filter_backends = (filters.DjangoFilterBackend,)\n filter_fields = ('category', 'in_stock')\n\n\n\nThis will automatically create a \nFilterSet\n class for the given fields, and will allow you to make requests such as:\n\n\nhttp://example.com/api/products?category=clothing\nin_stock=True\n\n\n\nSpecifying a FilterSet\n\n\nFor more advanced filtering requirements you can specify a \nFilterSet\n class that should be used by the view. For example:\n\n\nimport django_filters\nfrom myapp.models import Product\nfrom myapp.serializers import ProductSerializer\nfrom rest_framework import generics\n\nclass ProductFilter(django_filters.rest_framework.FilterSet):\n min_price = django_filters.NumberFilter(name=\"price\", lookup_expr='gte')\n max_price = django_filters.NumberFilter(name=\"price\", lookup_expr='lte')\n class Meta:\n model = Product\n fields = ['category', 'in_stock', 'min_price', 'max_price']\n\nclass ProductList(generics.ListAPIView):\n queryset = Product.objects.all()\n serializer_class = ProductSerializer\n filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)\n filter_class = ProductFilter\n\n\n\nWhich will allow you to make requests such as:\n\n\nhttp://example.com/api/products?category=clothing\nmax_price=10.00\n\n\n\nYou can also span relationships using \ndjango-filter\n, let's assume that each\nproduct has foreign key to \nManufacturer\n model, so we create filter that\nfilters using \nManufacturer\n name. For example:\n\n\nimport django_filters\nfrom myapp.models import Product\nfrom myapp.serializers import ProductSerializer\nfrom rest_framework import generics\n\nclass ProductFilter(django_filters.rest_framework.FilterSet):\n class Meta:\n model = Product\n fields = ['category', 'in_stock', 'manufacturer__name']\n\n\n\nThis enables us to make queries like:\n\n\nhttp://example.com/api/products?manufacturer__name=foo\n\n\n\nThis is nice, but it exposes the Django's double underscore convention as part of the API. If you instead want to explicitly name the filter argument you can instead explicitly include it on the \nFilterSet\n class:\n\n\nimport django_filters\nfrom myapp.models import Product\nfrom myapp.serializers import ProductSerializer\nfrom rest_framework import generics\n\nclass ProductFilter(django_filters.rest_framework.FilterSet):\n manufacturer = django_filters.CharFilter(name=\"manufacturer__name\")\n\n class Meta:\n model = Product\n fields = ['category', 'in_stock', 'manufacturer']\n\n\n\nAnd now you can execute:\n\n\nhttp://example.com/api/products?manufacturer=foo\n\n\n\nFor more details on using filter sets see the \ndjango-filter documentation\n.\n\n\n\n\nHints \n Tips\n\n\n\n\nBy default filtering is not enabled. If you want to use \nDjangoFilterBackend\n remember to make sure it is installed by using the \n'DEFAULT_FILTER_BACKENDS'\n setting.\n\n\nWhen using boolean fields, you should use the values \nTrue\n and \nFalse\n in the URL query parameters, rather than \n0\n, \n1\n, \ntrue\n or \nfalse\n. (The allowed boolean values are currently hardwired in Django's \nNullBooleanSelect implementation\n.)\n\n\ndjango-filter\n supports filtering across relationships, using Django's double-underscore syntax.\n\n\n\n\n\n\nSearchFilter\n\n\nThe \nSearchFilter\n class supports simple single query parameter based searching, and is based on the \nDjango admin's search functionality\n.\n\n\nWhen in use, the browsable API will include a \nSearchFilter\n control:\n\n\n\n\nThe \nSearchFilter\n class will only be applied if the view has a \nsearch_fields\n attribute set. The \nsearch_fields\n attribute should be a list of names of text type fields on the model, such as \nCharField\n or \nTextField\n.\n\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (filters.SearchFilter,)\n search_fields = ('username', 'email')\n\n\n\nThis will allow the client to filter the items in the list by making queries such as:\n\n\nhttp://example.com/api/users?search=russell\n\n\n\nYou can also perform a related lookup on a ForeignKey or ManyToManyField with the lookup API double-underscore notation:\n\n\nsearch_fields = ('username', 'email', 'profile__profession')\n\n\n\nBy default, searches will use case-insensitive partial matches. The search parameter may contain multiple search terms, which should be whitespace and/or comma separated. If multiple search terms are used then objects will be returned in the list only if all the provided terms are matched.\n\n\nThe search behavior may be restricted by prepending various characters to the \nsearch_fields\n.\n\n\n\n\n'^' Starts-with search.\n\n\n'=' Exact matches.\n\n\n'@' Full-text search. (Currently only supported Django's MySQL backend.)\n\n\n'$' Regex search.\n\n\n\n\nFor example:\n\n\nsearch_fields = ('=username', '=email')\n\n\n\nBy default, the search parameter is named \n'search\n', but this may be overridden with the \nSEARCH_PARAM\n setting.\n\n\nFor more details, see the \nDjango documentation\n.\n\n\n\n\nOrderingFilter\n\n\nThe \nOrderingFilter\n class supports simple query parameter controlled ordering of results.\n\n\n\n\nBy default, the query parameter is named \n'ordering'\n, but this may by overridden with the \nORDERING_PARAM\n setting.\n\n\nFor example, to order users by username:\n\n\nhttp://example.com/api/users?ordering=username\n\n\n\nThe client may also specify reverse orderings by prefixing the field name with '-', like so:\n\n\nhttp://example.com/api/users?ordering=-username\n\n\n\nMultiple orderings may also be specified:\n\n\nhttp://example.com/api/users?ordering=account,username\n\n\n\nSpecifying which fields may be ordered against\n\n\nIt's recommended that you explicitly specify which fields the API should allowing in the ordering filter. You can do this by setting an \nordering_fields\n attribute on the view, like so:\n\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (filters.OrderingFilter,)\n ordering_fields = ('username', 'email')\n\n\n\nThis helps prevent unexpected data leakage, such as allowing users to order against a password hash field or other sensitive data.\n\n\nIf you \ndon't\n specify an \nordering_fields\n attribute on the view, the filter class will default to allowing the user to filter on any readable fields on the serializer specified by the \nserializer_class\n attribute.\n\n\nIf you are confident that the queryset being used by the view doesn't contain any sensitive data, you can also explicitly specify that a view should allow ordering on \nany\n model field or queryset aggregate, by using the special value \n'__all__'\n.\n\n\nclass BookingsListView(generics.ListAPIView):\n queryset = Booking.objects.all()\n serializer_class = BookingSerializer\n filter_backends = (filters.OrderingFilter,)\n ordering_fields = '__all__'\n\n\n\nSpecifying a default ordering\n\n\nIf an \nordering\n attribute is set on the view, this will be used as the default ordering.\n\n\nTypically you'd instead control this by setting \norder_by\n on the initial queryset, but using the \nordering\n parameter on the view allows you to specify the ordering in a way that it can then be passed automatically as context to a rendered template. This makes it possible to automatically render column headers differently if they are being used to order the results.\n\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (filters.OrderingFilter,)\n ordering_fields = ('username', 'email')\n ordering = ('username',)\n\n\n\nThe \nordering\n attribute may be either a string or a list/tuple of strings.\n\n\n\n\nDjangoObjectPermissionsFilter\n\n\nThe \nDjangoObjectPermissionsFilter\n is intended to be used together with the \ndjango-guardian\n package, with custom \n'view'\n permissions added. The filter will ensure that querysets only returns objects for which the user has the appropriate view permission.\n\n\nIf you're using \nDjangoObjectPermissionsFilter\n, you'll probably also want to add an appropriate object permissions class, to ensure that users can only operate on instances if they have the appropriate object permissions. The easiest way to do this is to subclass \nDjangoObjectPermissions\n and add \n'view'\n permissions to the \nperms_map\n attribute.\n\n\nA complete example using both \nDjangoObjectPermissionsFilter\n and \nDjangoObjectPermissions\n might look something like this.\n\n\npermissions.py\n:\n\n\nclass CustomObjectPermissions(permissions.DjangoObjectPermissions):\n \"\"\"\n Similar to `DjangoObjectPermissions`, but adding 'view' permissions.\n \"\"\"\n perms_map = {\n 'GET': ['%(app_label)s.view_%(model_name)s'],\n 'OPTIONS': ['%(app_label)s.view_%(model_name)s'],\n 'HEAD': ['%(app_label)s.view_%(model_name)s'],\n 'POST': ['%(app_label)s.add_%(model_name)s'],\n 'PUT': ['%(app_label)s.change_%(model_name)s'],\n 'PATCH': ['%(app_label)s.change_%(model_name)s'],\n 'DELETE': ['%(app_label)s.delete_%(model_name)s'],\n }\n\n\n\nviews.py\n:\n\n\nclass EventViewSet(viewsets.ModelViewSet):\n \"\"\"\n Viewset that only lists events if user has 'view' permissions, and only\n allows operations on individual events if user has appropriate 'view', 'add',\n 'change' or 'delete' permissions.\n \"\"\"\n queryset = Event.objects.all()\n serializer_class = EventSerializer\n filter_backends = (filters.DjangoObjectPermissionsFilter,)\n permission_classes = (myapp.permissions.CustomObjectPermissions,)\n\n\n\nFor more information on adding \n'view'\n permissions for models, see the \nrelevant section\n of the \ndjango-guardian\n documentation, and \nthis blogpost\n.\n\n\n\n\nCustom generic filtering\n\n\nYou can also provide your own generic filtering backend, or write an installable app for other developers to use.\n\n\nTo do so override \nBaseFilterBackend\n, and override the \n.filter_queryset(self, request, queryset, view)\n method. The method should return a new, filtered queryset.\n\n\nAs well as allowing clients to perform searches and filtering, generic filter backends can be useful for restricting which objects should be visible to any given request or user.\n\n\nExample\n\n\nFor example, you might need to restrict users to only being able to see objects they created.\n\n\nclass IsOwnerFilterBackend(filters.BaseFilterBackend):\n \"\"\"\n Filter that only allows users to see their own objects.\n \"\"\"\n def filter_queryset(self, request, queryset, view):\n return queryset.filter(owner=request.user)\n\n\n\nWe could achieve the same behavior by overriding \nget_queryset()\n on the views, but using a filter backend allows you to more easily add this restriction to multiple views, or to apply it across the entire API.\n\n\nCustomizing the interface\n\n\nGeneric filters may also present an interface in the browsable API. To do so you should implement a \nto_html()\n method which returns a rendered HTML representation of the filter. This method should have the following signature:\n\n\nto_html(self, request, queryset, view)\n\n\nThe method should return a rendered HTML string.\n\n\nPagination \n schemas\n\n\nYou can also make the filter controls available to the schema autogeneration\nthat REST framework provides, by implementing a \nget_schema_fields()\n method,\nwhich should return a list of \ncoreapi.Field\n instances.\n\n\nThird party packages\n\n\nThe following third party packages provide additional filter implementations.\n\n\nDjango REST framework filters package\n\n\nThe \ndjango-rest-framework-filters package\n works together with the \nDjangoFilterBackend\n class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field.\n\n\nDjango REST framework full word search filter\n\n\nThe \ndjangorestframework-word-filter\n developed as alternative to \nfilters.SearchFilter\n which will search full word in text, or exact match.\n\n\nDjango URL Filter\n\n\ndjango-url-filter\n provides a safe way to filter data via human-friendly URLs. It works very similar to DRF serializers and fields in a sense that they can be nested except they are called filtersets and filters. That provides easy way to filter related data. Also this library is generic-purpose so it can be used to filter other sources of data and not only Django \nQuerySet\ns.\n\n\ndrf-url-filters\n\n\ndrf-url-filter\n is a simple Django app to apply filters on drf \nModelViewSet\n's \nQueryset\n in a clean, simple and configurable way. It also supports validations on incoming query params and their values. A beautiful python package \nVoluptuous\n is being used for validations on the incoming query parameters. The best part about voluptuous is you can define your own validations as per your query params requirements.", + "text": "Filtering\n\n\n\n\nThe root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects.\n\n\n \nDjango documentation\n\n\n\n\nThe default behavior of REST framework's generic list views is to return the entire queryset for a model manager. Often you will want your API to restrict the items that are returned by the queryset.\n\n\nThe simplest way to filter the queryset of any view that subclasses \nGenericAPIView\n is to override the \n.get_queryset()\n method.\n\n\nOverriding this method allows you to customize the queryset returned by the view in a number of different ways.\n\n\nFiltering against the current user\n\n\nYou might want to filter the queryset to ensure that only results relevant to the currently authenticated user making the request are returned.\n\n\nYou can do so by filtering based on the value of \nrequest.user\n.\n\n\nFor example:\n\n\nfrom myapp.models import Purchase\nfrom myapp.serializers import PurchaseSerializer\nfrom rest_framework import generics\n\nclass PurchaseList(generics.ListAPIView):\n serializer_class = PurchaseSerializer\n\n def get_queryset(self):\n \"\"\"\n This view should return a list of all the purchases\n for the currently authenticated user.\n \"\"\"\n user = self.request.user\n return Purchase.objects.filter(purchaser=user)\n\n\n\nFiltering against the URL\n\n\nAnother style of filtering might involve restricting the queryset based on some part of the URL.\n\n\nFor example if your URL config contained an entry like this:\n\n\nurl('^purchases/(?P\nusername\n.+)/$', PurchaseList.as_view()),\n\n\n\nYou could then write a view that returned a purchase queryset filtered by the username portion of the URL:\n\n\nclass PurchaseList(generics.ListAPIView):\n serializer_class = PurchaseSerializer\n\n def get_queryset(self):\n \"\"\"\n This view should return a list of all the purchases for\n the user as determined by the username portion of the URL.\n \"\"\"\n username = self.kwargs['username']\n return Purchase.objects.filter(purchaser__username=username)\n\n\n\nFiltering against query parameters\n\n\nA final example of filtering the initial queryset would be to determine the initial queryset based on query parameters in the url.\n\n\nWe can override \n.get_queryset()\n to deal with URLs such as \nhttp://example.com/api/purchases?username=denvercoder9\n, and filter the queryset only if the \nusername\n parameter is included in the URL:\n\n\nclass PurchaseList(generics.ListAPIView):\n serializer_class = PurchaseSerializer\n\n def get_queryset(self):\n \"\"\"\n Optionally restricts the returned purchases to a given user,\n by filtering against a `username` query parameter in the URL.\n \"\"\"\n queryset = Purchase.objects.all()\n username = self.request.query_params.get('username', None)\n if username is not None:\n queryset = queryset.filter(purchaser__username=username)\n return queryset\n\n\n\n\n\nGeneric Filtering\n\n\nAs well as being able to override the default queryset, REST framework also includes support for generic filtering backends that allow you to easily construct complex searches and filters.\n\n\nGeneric filters can also present themselves as HTML controls in the browsable API and admin API.\n\n\n\n\nSetting filter backends\n\n\nThe default filter backends may be set globally, using the \nDEFAULT_FILTER_BACKENDS\n setting. For example.\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)\n}\n\n\n\nYou can also set the filter backends on a per-view, or per-viewset basis,\nusing the \nGenericAPIView\n class-based views.\n\n\nimport django_filters.rest_framework\nfrom django.contrib.auth.models import User\nfrom myapp.serializers import UserSerializer\nfrom rest_framework import generics\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)\n\n\n\nFiltering and object lookups\n\n\nNote that if a filter backend is configured for a view, then as well as being used to filter list views, it will also be used to filter the querysets used for returning a single object.\n\n\nFor instance, given the previous example, and a product with an id of \n4675\n, the following URL would either return the corresponding object, or return a 404 response, depending on if the filtering conditions were met by the given product instance:\n\n\nhttp://example.com/api/products/4675/?category=clothing\nmax_price=10.00\n\n\n\nOverriding the initial queryset\n\n\nNote that you can use both an overridden \n.get_queryset()\n and generic filtering together, and everything will work as expected. For example, if \nProduct\n had a many-to-many relationship with \nUser\n, named \npurchase\n, you might want to write a view like this:\n\n\nclass PurchasedProductsList(generics.ListAPIView):\n \"\"\"\n Return a list of all the products that the authenticated\n user has ever purchased, with optional filtering.\n \"\"\"\n model = Product\n serializer_class = ProductSerializer\n filter_class = ProductFilter\n\n def get_queryset(self):\n user = self.request.user\n return user.purchase_set.all()\n\n\n\n\n\nAPI Guide\n\n\nDjangoFilterBackend\n\n\nThe \ndjango-filter\n library includes a \nDjangoFilterBackend\n class which\nsupports highly customizable field filtering for REST framework.\n\n\nTo use \nDjangoFilterBackend\n, first install \ndjango-filter\n.\n\n\npip install django-filter\n\n\n\nYou should now either add the filter backend to your settings:\n\n\nREST_FRAMEWORK = {\n 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)\n}\n\n\n\nOr add the filter backend to an individual View or ViewSet.\n\n\nfrom django_filters.rest_framework import DjangoFilterBackend\n\nclass UserListView(generics.ListAPIView):\n ...\n filter_backends = (DjangoFilterBackend,)\n\n\n\nIf you are using the browsable API or admin API you may also want to install \ndjango-crispy-forms\n, which will enhance the presentation of the filter forms in HTML views, by allowing them to render Bootstrap 3 HTML.\n\n\npip install django-crispy-forms\n\n\n\nWith crispy forms installed and added to Django's \nINSTALLED_APPS\n, the browsable API will present a filtering control for \nDjangoFilterBackend\n, like so:\n\n\n\n\nSpecifying filter fields\n\n\nIf all you need is simple equality-based filtering, you can set a \nfilter_fields\n attribute on the view, or viewset, listing the set of fields you wish to filter against.\n\n\nclass ProductList(generics.ListAPIView):\n queryset = Product.objects.all()\n serializer_class = ProductSerializer\n filter_backends = (filters.DjangoFilterBackend,)\n filter_fields = ('category', 'in_stock')\n\n\n\nThis will automatically create a \nFilterSet\n class for the given fields, and will allow you to make requests such as:\n\n\nhttp://example.com/api/products?category=clothing\nin_stock=True\n\n\n\nSpecifying a FilterSet\n\n\nFor more advanced filtering requirements you can specify a \nFilterSet\n class that should be used by the view. For example:\n\n\nimport django_filters\nfrom myapp.models import Product\nfrom myapp.serializers import ProductSerializer\nfrom rest_framework import generics\n\nclass ProductFilter(django_filters.rest_framework.FilterSet):\n min_price = django_filters.NumberFilter(name=\"price\", lookup_expr='gte')\n max_price = django_filters.NumberFilter(name=\"price\", lookup_expr='lte')\n class Meta:\n model = Product\n fields = ['category', 'in_stock', 'min_price', 'max_price']\n\nclass ProductList(generics.ListAPIView):\n queryset = Product.objects.all()\n serializer_class = ProductSerializer\n filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)\n filter_class = ProductFilter\n\n\n\nWhich will allow you to make requests such as:\n\n\nhttp://example.com/api/products?category=clothing\nmax_price=10.00\n\n\n\nYou can also span relationships using \ndjango-filter\n, let's assume that each\nproduct has foreign key to \nManufacturer\n model, so we create filter that\nfilters using \nManufacturer\n name. For example:\n\n\nimport django_filters\nfrom myapp.models import Product\nfrom myapp.serializers import ProductSerializer\nfrom rest_framework import generics\n\nclass ProductFilter(django_filters.rest_framework.FilterSet):\n class Meta:\n model = Product\n fields = ['category', 'in_stock', 'manufacturer__name']\n\n\n\nThis enables us to make queries like:\n\n\nhttp://example.com/api/products?manufacturer__name=foo\n\n\n\nThis is nice, but it exposes the Django's double underscore convention as part of the API. If you instead want to explicitly name the filter argument you can instead explicitly include it on the \nFilterSet\n class:\n\n\nimport django_filters\nfrom myapp.models import Product\nfrom myapp.serializers import ProductSerializer\nfrom rest_framework import generics\n\nclass ProductFilter(django_filters.rest_framework.FilterSet):\n manufacturer = django_filters.CharFilter(name=\"manufacturer__name\")\n\n class Meta:\n model = Product\n fields = ['category', 'in_stock', 'manufacturer']\n\n\n\nAnd now you can execute:\n\n\nhttp://example.com/api/products?manufacturer=foo\n\n\n\nFor more details on using filter sets see the \ndjango-filter documentation\n.\n\n\n\n\nHints \n Tips\n\n\n\n\nBy default filtering is not enabled. If you want to use \nDjangoFilterBackend\n remember to make sure it is installed by using the \n'DEFAULT_FILTER_BACKENDS'\n setting.\n\n\nWhen using boolean fields, you should use the values \nTrue\n and \nFalse\n in the URL query parameters, rather than \n0\n, \n1\n, \ntrue\n or \nfalse\n. (The allowed boolean values are currently hardwired in Django's \nNullBooleanSelect implementation\n.)\n\n\ndjango-filter\n supports filtering across relationships, using Django's double-underscore syntax.\n\n\n\n\n\n\nSearchFilter\n\n\nThe \nSearchFilter\n class supports simple single query parameter based searching, and is based on the \nDjango admin's search functionality\n.\n\n\nWhen in use, the browsable API will include a \nSearchFilter\n control:\n\n\n\n\nThe \nSearchFilter\n class will only be applied if the view has a \nsearch_fields\n attribute set. The \nsearch_fields\n attribute should be a list of names of text type fields on the model, such as \nCharField\n or \nTextField\n.\n\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (filters.SearchFilter,)\n search_fields = ('username', 'email')\n\n\n\nThis will allow the client to filter the items in the list by making queries such as:\n\n\nhttp://example.com/api/users?search=russell\n\n\n\nYou can also perform a related lookup on a ForeignKey or ManyToManyField with the lookup API double-underscore notation:\n\n\nsearch_fields = ('username', 'email', 'profile__profession')\n\n\n\nBy default, searches will use case-insensitive partial matches. The search parameter may contain multiple search terms, which should be whitespace and/or comma separated. If multiple search terms are used then objects will be returned in the list only if all the provided terms are matched.\n\n\nThe search behavior may be restricted by prepending various characters to the \nsearch_fields\n.\n\n\n\n\n'^' Starts-with search.\n\n\n'=' Exact matches.\n\n\n'@' Full-text search. (Currently only supported Django's MySQL backend.)\n\n\n'$' Regex search.\n\n\n\n\nFor example:\n\n\nsearch_fields = ('=username', '=email')\n\n\n\nBy default, the search parameter is named \n'search\n', but this may be overridden with the \nSEARCH_PARAM\n setting.\n\n\nFor more details, see the \nDjango documentation\n.\n\n\n\n\nOrderingFilter\n\n\nThe \nOrderingFilter\n class supports simple query parameter controlled ordering of results.\n\n\n\n\nBy default, the query parameter is named \n'ordering'\n, but this may by overridden with the \nORDERING_PARAM\n setting.\n\n\nFor example, to order users by username:\n\n\nhttp://example.com/api/users?ordering=username\n\n\n\nThe client may also specify reverse orderings by prefixing the field name with '-', like so:\n\n\nhttp://example.com/api/users?ordering=-username\n\n\n\nMultiple orderings may also be specified:\n\n\nhttp://example.com/api/users?ordering=account,username\n\n\n\nSpecifying which fields may be ordered against\n\n\nIt's recommended that you explicitly specify which fields the API should allowing in the ordering filter. You can do this by setting an \nordering_fields\n attribute on the view, like so:\n\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (filters.OrderingFilter,)\n ordering_fields = ('username', 'email')\n\n\n\nThis helps prevent unexpected data leakage, such as allowing users to order against a password hash field or other sensitive data.\n\n\nIf you \ndon't\n specify an \nordering_fields\n attribute on the view, the filter class will default to allowing the user to filter on any readable fields on the serializer specified by the \nserializer_class\n attribute.\n\n\nIf you are confident that the queryset being used by the view doesn't contain any sensitive data, you can also explicitly specify that a view should allow ordering on \nany\n model field or queryset aggregate, by using the special value \n'__all__'\n.\n\n\nclass BookingsListView(generics.ListAPIView):\n queryset = Booking.objects.all()\n serializer_class = BookingSerializer\n filter_backends = (filters.OrderingFilter,)\n ordering_fields = '__all__'\n\n\n\nSpecifying a default ordering\n\n\nIf an \nordering\n attribute is set on the view, this will be used as the default ordering.\n\n\nTypically you'd instead control this by setting \norder_by\n on the initial queryset, but using the \nordering\n parameter on the view allows you to specify the ordering in a way that it can then be passed automatically as context to a rendered template. This makes it possible to automatically render column headers differently if they are being used to order the results.\n\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (filters.OrderingFilter,)\n ordering_fields = ('username', 'email')\n ordering = ('username',)\n\n\n\nThe \nordering\n attribute may be either a string or a list/tuple of strings.\n\n\n\n\nDjangoObjectPermissionsFilter\n\n\nThe \nDjangoObjectPermissionsFilter\n is intended to be used together with the \ndjango-guardian\n package, with custom \n'view'\n permissions added. The filter will ensure that querysets only returns objects for which the user has the appropriate view permission.\n\n\nIf you're using \nDjangoObjectPermissionsFilter\n, you'll probably also want to add an appropriate object permissions class, to ensure that users can only operate on instances if they have the appropriate object permissions. The easiest way to do this is to subclass \nDjangoObjectPermissions\n and add \n'view'\n permissions to the \nperms_map\n attribute.\n\n\nA complete example using both \nDjangoObjectPermissionsFilter\n and \nDjangoObjectPermissions\n might look something like this.\n\n\npermissions.py\n:\n\n\nclass CustomObjectPermissions(permissions.DjangoObjectPermissions):\n \"\"\"\n Similar to `DjangoObjectPermissions`, but adding 'view' permissions.\n \"\"\"\n perms_map = {\n 'GET': ['%(app_label)s.view_%(model_name)s'],\n 'OPTIONS': ['%(app_label)s.view_%(model_name)s'],\n 'HEAD': ['%(app_label)s.view_%(model_name)s'],\n 'POST': ['%(app_label)s.add_%(model_name)s'],\n 'PUT': ['%(app_label)s.change_%(model_name)s'],\n 'PATCH': ['%(app_label)s.change_%(model_name)s'],\n 'DELETE': ['%(app_label)s.delete_%(model_name)s'],\n }\n\n\n\nviews.py\n:\n\n\nclass EventViewSet(viewsets.ModelViewSet):\n \"\"\"\n Viewset that only lists events if user has 'view' permissions, and only\n allows operations on individual events if user has appropriate 'view', 'add',\n 'change' or 'delete' permissions.\n \"\"\"\n queryset = Event.objects.all()\n serializer_class = EventSerializer\n filter_backends = (filters.DjangoObjectPermissionsFilter,)\n permission_classes = (myapp.permissions.CustomObjectPermissions,)\n\n\n\nFor more information on adding \n'view'\n permissions for models, see the \nrelevant section\n of the \ndjango-guardian\n documentation, and \nthis blogpost\n.\n\n\n\n\nCustom generic filtering\n\n\nYou can also provide your own generic filtering backend, or write an installable app for other developers to use.\n\n\nTo do so override \nBaseFilterBackend\n, and override the \n.filter_queryset(self, request, queryset, view)\n method. The method should return a new, filtered queryset.\n\n\nAs well as allowing clients to perform searches and filtering, generic filter backends can be useful for restricting which objects should be visible to any given request or user.\n\n\nExample\n\n\nFor example, you might need to restrict users to only being able to see objects they created.\n\n\nclass IsOwnerFilterBackend(filters.BaseFilterBackend):\n \"\"\"\n Filter that only allows users to see their own objects.\n \"\"\"\n def filter_queryset(self, request, queryset, view):\n return queryset.filter(owner=request.user)\n\n\n\nWe could achieve the same behavior by overriding \nget_queryset()\n on the views, but using a filter backend allows you to more easily add this restriction to multiple views, or to apply it across the entire API.\n\n\nCustomizing the interface\n\n\nGeneric filters may also present an interface in the browsable API. To do so you should implement a \nto_html()\n method which returns a rendered HTML representation of the filter. This method should have the following signature:\n\n\nto_html(self, request, queryset, view)\n\n\nThe method should return a rendered HTML string.\n\n\nPagination \n schemas\n\n\nYou can also make the filter controls available to the schema autogeneration\nthat REST framework provides, by implementing a \nget_schema_fields()\n method,\nwhich should return a list of \ncoreapi.Field\n instances.\n\n\nThird party packages\n\n\nThe following third party packages provide additional filter implementations.\n\n\nDjango REST framework filters package\n\n\nThe \ndjango-rest-framework-filters package\n works together with the \nDjangoFilterBackend\n class, and allows you to easily create filters across relationships, or create multiple filter lookup types for a given field.\n\n\nDjango REST framework full word search filter\n\n\nThe \ndjangorestframework-word-filter\n developed as alternative to \nfilters.SearchFilter\n which will search full word in text, or exact match.\n\n\nDjango URL Filter\n\n\ndjango-url-filter\n provides a safe way to filter data via human-friendly URLs. It works very similar to DRF serializers and fields in a sense that they can be nested except they are called filtersets and filters. That provides easy way to filter related data. Also this library is generic-purpose so it can be used to filter other sources of data and not only Django \nQuerySet\ns.\n\n\ndrf-url-filters\n\n\ndrf-url-filter\n is a simple Django app to apply filters on drf \nModelViewSet\n's \nQueryset\n in a clean, simple and configurable way. It also supports validations on incoming query params and their values. A beautiful python package \nVoluptuous\n is being used for validations on the incoming query parameters. The best part about voluptuous is you can define your own validations as per your query params requirements.", "title": "Filtering" }, { @@ -2637,7 +2637,7 @@ }, { "location": "/api-guide/filtering/#setting-filter-backends", - "text": "The default filter backends may be set globally, using the DEFAULT_FILTER_BACKENDS setting. For example. REST_FRAMEWORK = {\n 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)\n} You can also set the filter backends on a per-view, or per-viewset basis,\nusing the GenericAPIView class-based views. import django_filters\nfrom django.contrib.auth.models import User\nfrom myapp.serializers import UserSerializer\nfrom rest_framework import generics\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)", + "text": "The default filter backends may be set globally, using the DEFAULT_FILTER_BACKENDS setting. For example. REST_FRAMEWORK = {\n 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)\n} You can also set the filter backends on a per-view, or per-viewset basis,\nusing the GenericAPIView class-based views. import django_filters.rest_framework\nfrom django.contrib.auth.models import User\nfrom myapp.serializers import UserSerializer\nfrom rest_framework import generics\n\nclass UserListView(generics.ListAPIView):\n queryset = User.objects.all()\n serializer_class = UserSerializer\n filter_backends = (django_filters.rest_framework.DjangoFilterBackend,)", "title": "Setting filter backends" }, { @@ -3287,7 +3287,7 @@ }, { "location": "/api-guide/exceptions/", - "text": "Exceptions\n\n\n\n\nExceptions\u2026 allow error handling to be organized cleanly in a central or high-level place within the program structure.\n\n\n Doug Hellmann, \nPython Exception Handling Techniques\n\n\n\n\nException handling in REST framework views\n\n\nREST framework's views handle various exceptions, and deal with returning appropriate error responses.\n\n\nThe handled exceptions are:\n\n\n\n\nSubclasses of \nAPIException\n raised inside REST framework.\n\n\nDjango's \nHttp404\n exception.\n\n\nDjango's \nPermissionDenied\n exception.\n\n\n\n\nIn each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.\n\n\nMost error responses will include a key \ndetail\n in the body of the response.\n\n\nFor example, the following request:\n\n\nDELETE http://api.example.com/foo/bar HTTP/1.1\nAccept: application/json\n\n\n\nMight receive an error response indicating that the \nDELETE\n method is not allowed on that resource:\n\n\nHTTP/1.1 405 Method Not Allowed\nContent-Type: application/json\nContent-Length: 42\n\n{\"detail\": \"Method 'DELETE' not allowed.\"}\n\n\n\nValidation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the \"non_field_errors\" key, or whatever string value has been set for the \nNON_FIELD_ERRORS_KEY\n setting.\n\n\nAny example validation error might look like this:\n\n\nHTTP/1.1 400 Bad Request\nContent-Type: application/json\nContent-Length: 94\n\n{\"amount\": [\"A valid integer is required.\"], \"description\": [\"This field may not be blank.\"]}\n\n\n\nCustom exception handling\n\n\nYou can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.\n\n\nThe function must take a pair of arguments, this first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a \nResponse\n object, or return \nNone\n if the exception cannot be handled. If the handler returns \nNone\n then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.\n\n\nFor example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:\n\n\nHTTP/1.1 405 Method Not Allowed\nContent-Type: application/json\nContent-Length: 62\n\n{\"status_code\": 405, \"detail\": \"Method 'DELETE' not allowed.\"}\n\n\n\nIn order to alter the style of the response, you could write the following custom exception handler:\n\n\nfrom rest_framework.views import exception_handler\n\ndef custom_exception_handler(exc, context):\n # Call REST framework's default exception handler first,\n # to get the standard error response.\n response = exception_handler(exc, context)\n\n #\u00a0Now add the HTTP status code to the response.\n if response is not None:\n response.data['status_code'] = response.status_code\n\n return response\n\n\n\nThe context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as \ncontext['view']\n.\n\n\nThe exception handler must also be configured in your settings, using the \nEXCEPTION_HANDLER\n setting key. For example:\n\n\nREST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'\n}\n\n\n\nIf not specified, the \n'EXCEPTION_HANDLER'\n setting defaults to the standard exception handler provided by REST framework:\n\n\nREST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'\n}\n\n\n\nNote that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the \nHTTP_400_BAD_REQUEST\n responses that are returned by the generic views when serializer validation fails.\n\n\n\n\nAPI Reference\n\n\nAPIException\n\n\nSignature:\n \nAPIException()\n\n\nThe \nbase class\n for all exceptions raised inside an \nAPIView\n class or \n@api_view\n.\n\n\nTo provide a custom exception, subclass \nAPIException\n and set the \n.status_code\n, \n.default_detail\n, and \ndefault_code\n attributes on the class.\n\n\nFor example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the \"503 Service Unavailable\" HTTP response code. You could do this like so:\n\n\nfrom rest_framework.exceptions import APIException\n\nclass ServiceUnavailable(APIException):\n status_code = 503\n default_detail = 'Service temporarily unavailable, try again later.'\n default_code = 'service_unavailable'\n\n\n\nInspecting API exceptions\n\n\nThere are a number of different properties available for inspecting the status\nof an API exception. You can use these to build custom exception handling\nfor your project.\n\n\nThe available attributes and methods are:\n\n\n\n\n.detail\n - Return the textual description of the error.\n\n\n.get_codes()\n - Return the code identifier of the error.\n\n\n.get_full_details()\n - Return both the textual description and the code identifier.\n\n\n\n\nIn most cases the error detail will be a simple item:\n\n\n print(exc.detail)\nYou do not have permission to perform this action.\n\n print(exc.get_codes())\npermission_denied\n\n print(exc.get_full_details())\n{'message':'You do not have permission to perform this action.','code':'permission_denied'}\n\n\n\nIn the case of validation errors the error detail will be either a list or\ndictionary of items:\n\n\n print(exc.detail)\n{\"name\":\"This field is required.\",\"age\":\"A valid integer is required.\"}\n\n print(exc.get_codes())\n{\"name\":\"required\",\"age\":\"invalid\"}\n\n print(exc.get_full_details())\n{\"name\":{\"message\":\"This field is required.\",\"code\":\"required\"},\"age\":{\"message\":\"A valid integer is required.\",\"code\":\"invalid\"}}\n\n\n\nParseError\n\n\nSignature:\n \nParseError(detail=None, code=None)\n\n\nRaised if the request contains malformed data when accessing \nrequest.data\n.\n\n\nBy default this exception results in a response with the HTTP status code \"400 Bad Request\".\n\n\nAuthenticationFailed\n\n\nSignature:\n \nAuthenticationFailed(detail=None, code=None)\n\n\nRaised when an incoming request includes incorrect authentication.\n\n\nBy default this exception results in a response with the HTTP status code \"401 Unauthenticated\", but it may also result in a \"403 Forbidden\" response, depending on the authentication scheme in use. See the \nauthentication documentation\n for more details.\n\n\nNotAuthenticated\n\n\nSignature:\n \nNotAuthenticated(detail=None, code=None)\n\n\nRaised when an unauthenticated request fails the permission checks.\n\n\nBy default this exception results in a response with the HTTP status code \"401 Unauthenticated\", but it may also result in a \"403 Forbidden\" response, depending on the authentication scheme in use. See the \nauthentication documentation\n for more details.\n\n\nPermissionDenied\n\n\nSignature:\n \nPermissionDenied(detail=None, code=None)\n\n\nRaised when an authenticated request fails the permission checks.\n\n\nBy default this exception results in a response with the HTTP status code \"403 Forbidden\".\n\n\nNotFound\n\n\nSignature:\n \nNotFound(detail=None, code=None)\n\n\nRaised when a resource does not exists at the given URL. This exception is equivalent to the standard \nHttp404\n Django exception.\n\n\nBy default this exception results in a response with the HTTP status code \"404 Not Found\".\n\n\nMethodNotAllowed\n\n\nSignature:\n \nMethodNotAllowed(method, detail=None, code=None)\n\n\nRaised when an incoming request occurs that does not map to a handler method on the view.\n\n\nBy default this exception results in a response with the HTTP status code \"405 Method Not Allowed\".\n\n\nNotAcceptable\n\n\nSignature:\n \nNotAcceptable(detail=None, code=None)\n\n\nRaised when an incoming request occurs with an \nAccept\n header that cannot be satisfied by any of the available renderers.\n\n\nBy default this exception results in a response with the HTTP status code \"406 Not Acceptable\".\n\n\nUnsupportedMediaType\n\n\nSignature:\n \nUnsupportedMediaType(media_type, detail=None, code=None)\n\n\nRaised if there are no parsers that can handle the content type of the request data when accessing \nrequest.data\n.\n\n\nBy default this exception results in a response with the HTTP status code \"415 Unsupported Media Type\".\n\n\nThrottled\n\n\nSignature:\n \nThrottled(wait=None, detail=None, code=None)\n\n\nRaised when an incoming request fails the throttling checks.\n\n\nBy default this exception results in a response with the HTTP status code \"429 Too Many Requests\".\n\n\nValidationError\n\n\nSignature:\n \nValidationError(detail, code=None)\n\n\nThe \nValidationError\n exception is slightly different from the other \nAPIException\n classes:\n\n\n\n\nThe \ndetail\n argument is mandatory, not optional.\n\n\nThe \ndetail\n argument may be a list or dictionary of error details, and may also be a nested data structure.\n\n\nBy convention you should import the serializers module and use a fully qualified \nValidationError\n style, in order to differentiate it from Django's built-in validation error. For example. \nraise serializers.ValidationError('This field must be an integer value.')\n\n\n\n\nThe \nValidationError\n class should be used for serializer and field validation, and by validator classes. It is also raised when calling \nserializer.is_valid\n with the \nraise_exception\n keyword argument:\n\n\nserializer.is_valid(raise_exception=True)\n\n\n\nThe generic views use the \nraise_exception=True\n flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above.\n\n\nBy default this exception results in a response with the HTTP status code \"400 Bad Request\".", + "text": "Exceptions\n\n\n\n\nExceptions\u2026 allow error handling to be organized cleanly in a central or high-level place within the program structure.\n\n\n Doug Hellmann, \nPython Exception Handling Techniques\n\n\n\n\nException handling in REST framework views\n\n\nREST framework's views handle various exceptions, and deal with returning appropriate error responses.\n\n\nThe handled exceptions are:\n\n\n\n\nSubclasses of \nAPIException\n raised inside REST framework.\n\n\nDjango's \nHttp404\n exception.\n\n\nDjango's \nPermissionDenied\n exception.\n\n\n\n\nIn each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.\n\n\nMost error responses will include a key \ndetail\n in the body of the response.\n\n\nFor example, the following request:\n\n\nDELETE http://api.example.com/foo/bar HTTP/1.1\nAccept: application/json\n\n\n\nMight receive an error response indicating that the \nDELETE\n method is not allowed on that resource:\n\n\nHTTP/1.1 405 Method Not Allowed\nContent-Type: application/json\nContent-Length: 42\n\n{\"detail\": \"Method 'DELETE' not allowed.\"}\n\n\n\nValidation errors are handled slightly differently, and will include the field names as the keys in the response. If the validation error was not specific to a particular field then it will use the \"non_field_errors\" key, or whatever string value has been set for the \nNON_FIELD_ERRORS_KEY\n setting.\n\n\nAny example validation error might look like this:\n\n\nHTTP/1.1 400 Bad Request\nContent-Type: application/json\nContent-Length: 94\n\n{\"amount\": [\"A valid integer is required.\"], \"description\": [\"This field may not be blank.\"]}\n\n\n\nCustom exception handling\n\n\nYou can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API.\n\n\nThe function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a \nResponse\n object, or return \nNone\n if the exception cannot be handled. If the handler returns \nNone\n then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.\n\n\nFor example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so:\n\n\nHTTP/1.1 405 Method Not Allowed\nContent-Type: application/json\nContent-Length: 62\n\n{\"status_code\": 405, \"detail\": \"Method 'DELETE' not allowed.\"}\n\n\n\nIn order to alter the style of the response, you could write the following custom exception handler:\n\n\nfrom rest_framework.views import exception_handler\n\ndef custom_exception_handler(exc, context):\n # Call REST framework's default exception handler first,\n # to get the standard error response.\n response = exception_handler(exc, context)\n\n #\u00a0Now add the HTTP status code to the response.\n if response is not None:\n response.data['status_code'] = response.status_code\n\n return response\n\n\n\nThe context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as \ncontext['view']\n.\n\n\nThe exception handler must also be configured in your settings, using the \nEXCEPTION_HANDLER\n setting key. For example:\n\n\nREST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'\n}\n\n\n\nIf not specified, the \n'EXCEPTION_HANDLER'\n setting defaults to the standard exception handler provided by REST framework:\n\n\nREST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'\n}\n\n\n\nNote that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the \nHTTP_400_BAD_REQUEST\n responses that are returned by the generic views when serializer validation fails.\n\n\n\n\nAPI Reference\n\n\nAPIException\n\n\nSignature:\n \nAPIException()\n\n\nThe \nbase class\n for all exceptions raised inside an \nAPIView\n class or \n@api_view\n.\n\n\nTo provide a custom exception, subclass \nAPIException\n and set the \n.status_code\n, \n.default_detail\n, and \ndefault_code\n attributes on the class.\n\n\nFor example, if your API relies on a third party service that may sometimes be unreachable, you might want to implement an exception for the \"503 Service Unavailable\" HTTP response code. You could do this like so:\n\n\nfrom rest_framework.exceptions import APIException\n\nclass ServiceUnavailable(APIException):\n status_code = 503\n default_detail = 'Service temporarily unavailable, try again later.'\n default_code = 'service_unavailable'\n\n\n\nInspecting API exceptions\n\n\nThere are a number of different properties available for inspecting the status\nof an API exception. You can use these to build custom exception handling\nfor your project.\n\n\nThe available attributes and methods are:\n\n\n\n\n.detail\n - Return the textual description of the error.\n\n\n.get_codes()\n - Return the code identifier of the error.\n\n\n.get_full_details()\n - Return both the textual description and the code identifier.\n\n\n\n\nIn most cases the error detail will be a simple item:\n\n\n print(exc.detail)\nYou do not have permission to perform this action.\n\n print(exc.get_codes())\npermission_denied\n\n print(exc.get_full_details())\n{'message':'You do not have permission to perform this action.','code':'permission_denied'}\n\n\n\nIn the case of validation errors the error detail will be either a list or\ndictionary of items:\n\n\n print(exc.detail)\n{\"name\":\"This field is required.\",\"age\":\"A valid integer is required.\"}\n\n print(exc.get_codes())\n{\"name\":\"required\",\"age\":\"invalid\"}\n\n print(exc.get_full_details())\n{\"name\":{\"message\":\"This field is required.\",\"code\":\"required\"},\"age\":{\"message\":\"A valid integer is required.\",\"code\":\"invalid\"}}\n\n\n\nParseError\n\n\nSignature:\n \nParseError(detail=None, code=None)\n\n\nRaised if the request contains malformed data when accessing \nrequest.data\n.\n\n\nBy default this exception results in a response with the HTTP status code \"400 Bad Request\".\n\n\nAuthenticationFailed\n\n\nSignature:\n \nAuthenticationFailed(detail=None, code=None)\n\n\nRaised when an incoming request includes incorrect authentication.\n\n\nBy default this exception results in a response with the HTTP status code \"401 Unauthenticated\", but it may also result in a \"403 Forbidden\" response, depending on the authentication scheme in use. See the \nauthentication documentation\n for more details.\n\n\nNotAuthenticated\n\n\nSignature:\n \nNotAuthenticated(detail=None, code=None)\n\n\nRaised when an unauthenticated request fails the permission checks.\n\n\nBy default this exception results in a response with the HTTP status code \"401 Unauthenticated\", but it may also result in a \"403 Forbidden\" response, depending on the authentication scheme in use. See the \nauthentication documentation\n for more details.\n\n\nPermissionDenied\n\n\nSignature:\n \nPermissionDenied(detail=None, code=None)\n\n\nRaised when an authenticated request fails the permission checks.\n\n\nBy default this exception results in a response with the HTTP status code \"403 Forbidden\".\n\n\nNotFound\n\n\nSignature:\n \nNotFound(detail=None, code=None)\n\n\nRaised when a resource does not exists at the given URL. This exception is equivalent to the standard \nHttp404\n Django exception.\n\n\nBy default this exception results in a response with the HTTP status code \"404 Not Found\".\n\n\nMethodNotAllowed\n\n\nSignature:\n \nMethodNotAllowed(method, detail=None, code=None)\n\n\nRaised when an incoming request occurs that does not map to a handler method on the view.\n\n\nBy default this exception results in a response with the HTTP status code \"405 Method Not Allowed\".\n\n\nNotAcceptable\n\n\nSignature:\n \nNotAcceptable(detail=None, code=None)\n\n\nRaised when an incoming request occurs with an \nAccept\n header that cannot be satisfied by any of the available renderers.\n\n\nBy default this exception results in a response with the HTTP status code \"406 Not Acceptable\".\n\n\nUnsupportedMediaType\n\n\nSignature:\n \nUnsupportedMediaType(media_type, detail=None, code=None)\n\n\nRaised if there are no parsers that can handle the content type of the request data when accessing \nrequest.data\n.\n\n\nBy default this exception results in a response with the HTTP status code \"415 Unsupported Media Type\".\n\n\nThrottled\n\n\nSignature:\n \nThrottled(wait=None, detail=None, code=None)\n\n\nRaised when an incoming request fails the throttling checks.\n\n\nBy default this exception results in a response with the HTTP status code \"429 Too Many Requests\".\n\n\nValidationError\n\n\nSignature:\n \nValidationError(detail, code=None)\n\n\nThe \nValidationError\n exception is slightly different from the other \nAPIException\n classes:\n\n\n\n\nThe \ndetail\n argument is mandatory, not optional.\n\n\nThe \ndetail\n argument may be a list or dictionary of error details, and may also be a nested data structure.\n\n\nBy convention you should import the serializers module and use a fully qualified \nValidationError\n style, in order to differentiate it from Django's built-in validation error. For example. \nraise serializers.ValidationError('This field must be an integer value.')\n\n\n\n\nThe \nValidationError\n class should be used for serializer and field validation, and by validator classes. It is also raised when calling \nserializer.is_valid\n with the \nraise_exception\n keyword argument:\n\n\nserializer.is_valid(raise_exception=True)\n\n\n\nThe generic views use the \nraise_exception=True\n flag, which means that you can override the style of validation error responses globally in your API. To do so, use a custom exception handler, as described above.\n\n\nBy default this exception results in a response with the HTTP status code \"400 Bad Request\".", "title": "Exceptions" }, { @@ -3302,7 +3302,7 @@ }, { "location": "/api-guide/exceptions/#custom-exception-handling", - "text": "You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API. The function must take a pair of arguments, this first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response. For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so: HTTP/1.1 405 Method Not Allowed\nContent-Type: application/json\nContent-Length: 62\n\n{\"status_code\": 405, \"detail\": \"Method 'DELETE' not allowed.\"} In order to alter the style of the response, you could write the following custom exception handler: from rest_framework.views import exception_handler\n\ndef custom_exception_handler(exc, context):\n # Call REST framework's default exception handler first,\n # to get the standard error response.\n response = exception_handler(exc, context)\n\n #\u00a0Now add the HTTP status code to the response.\n if response is not None:\n response.data['status_code'] = response.status_code\n\n return response The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view'] . The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example: REST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'\n} If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework: REST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'\n} Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails.", + "text": "You can implement custom exception handling by creating a handler function that converts exceptions raised in your API views into response objects. This allows you to control the style of error responses used by your API. The function must take a pair of arguments, the first is the exception to be handled, and the second is a dictionary containing any extra context such as the view currently being handled. The exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response. For example, you might want to ensure that all error responses include the HTTP status code in the body of the response, like so: HTTP/1.1 405 Method Not Allowed\nContent-Type: application/json\nContent-Length: 62\n\n{\"status_code\": 405, \"detail\": \"Method 'DELETE' not allowed.\"} In order to alter the style of the response, you could write the following custom exception handler: from rest_framework.views import exception_handler\n\ndef custom_exception_handler(exc, context):\n # Call REST framework's default exception handler first,\n # to get the standard error response.\n response = exception_handler(exc, context)\n\n #\u00a0Now add the HTTP status code to the response.\n if response is not None:\n response.data['status_code'] = response.status_code\n\n return response The context argument is not used by the default handler, but can be useful if the exception handler needs further information such as the view currently being handled, which can be accessed as context['view'] . The exception handler must also be configured in your settings, using the EXCEPTION_HANDLER setting key. For example: REST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'\n} If not specified, the 'EXCEPTION_HANDLER' setting defaults to the standard exception handler provided by REST framework: REST_FRAMEWORK = {\n 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'\n} Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails.", "title": "Custom exception handling" }, { @@ -3412,7 +3412,7 @@ }, { "location": "/api-guide/testing/", - "text": "Testing\n\n\n\n\nCode without tests is broken as designed.\n\n\n \nJacob Kaplan-Moss\n\n\n\n\nREST framework includes a few helper classes that extend Django's existing test framework, and improve support for making API requests.\n\n\nAPIRequestFactory\n\n\nExtends \nDjango's existing \nRequestFactory\n class\n.\n\n\nCreating test requests\n\n\nThe \nAPIRequestFactory\n class supports an almost identical API to Django's standard \nRequestFactory\n class. This means that the standard \n.get()\n, \n.post()\n, \n.put()\n, \n.patch()\n, \n.delete()\n, \n.head()\n and \n.options()\n methods are all available.\n\n\nfrom rest_framework.test import APIRequestFactory\n\n# Using the standard RequestFactory API to create a form POST request\nfactory = APIRequestFactory()\nrequest = factory.post('/notes/', {'title': 'new idea'})\n\n\n\nUsing the \nformat\n argument\n\n\nMethods which create a request body, such as \npost\n, \nput\n and \npatch\n, include a \nformat\n argument, which make it easy to generate requests using a content type other than multipart form data. For example:\n\n\n# Create a JSON POST request\nfactory = APIRequestFactory()\nrequest = factory.post('/notes/', {'title': 'new idea'}, format='json')\n\n\n\nBy default the available formats are \n'multipart'\n and \n'json'\n. For compatibility with Django's existing \nRequestFactory\n the default format is \n'multipart'\n.\n\n\nTo support a wider set of request formats, or change the default format, \nsee the configuration section\n.\n\n\nExplicitly encoding the request body\n\n\nIf you need to explicitly encode the request body, you can do so by setting the \ncontent_type\n flag. For example:\n\n\nrequest = factory.post('/notes/', json.dumps({'title': 'new idea'}), content_type='application/json')\n\n\n\nPUT and PATCH with form data\n\n\nOne difference worth noting between Django's \nRequestFactory\n and REST framework's \nAPIRequestFactory\n is that multipart form data will be encoded for methods other than just \n.post()\n.\n\n\nFor example, using \nAPIRequestFactory\n, you can make a form PUT request like so:\n\n\nfactory = APIRequestFactory()\nrequest = factory.put('/notes/547/', {'title': 'remember to email dave'})\n\n\n\nUsing Django's \nRequestFactory\n, you'd need to explicitly encode the data yourself:\n\n\nfrom django.test.client import encode_multipart, RequestFactory\n\nfactory = RequestFactory()\ndata = {'title': 'remember to email dave'}\ncontent = encode_multipart('BoUnDaRyStRiNg', data)\ncontent_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'\nrequest = factory.put('/notes/547/', content, content_type=content_type)\n\n\n\nForcing authentication\n\n\nWhen testing views directly using a request factory, it's often convenient to be able to directly authenticate the request, rather than having to construct the correct authentication credentials.\n\n\nTo forcibly authenticate a request, use the \nforce_authenticate()\n method.\n\n\nfrom rest_framework.test import force_authenticate\n\nfactory = APIRequestFactory()\nuser = User.objects.get(username='olivia')\nview = AccountDetail.as_view()\n\n# Make an authenticated request to the view...\nrequest = factory.get('/accounts/django-superstars/')\nforce_authenticate(request, user=user)\nresponse = view(request)\n\n\n\nThe signature for the method is \nforce_authenticate(request, user=None, token=None)\n. When making the call, either or both of the user and token may be set.\n\n\nFor example, when forcibly authenticating using a token, you might do something like the following:\n\n\nuser = User.objects.get(username='olivia')\nrequest = factory.get('/accounts/django-superstars/')\nforce_authenticate(request, user=user, token=user.token)\n\n\n\n\n\nNote\n: When using \nAPIRequestFactory\n, the object that is returned is Django's standard \nHttpRequest\n, and not REST framework's \nRequest\n object, which is only generated once the view is called.\n\n\nThis means that setting attributes directly on the request object may not always have the effect you expect. For example, setting \n.token\n directly will have no effect, and setting \n.user\n directly will only work if session authentication is being used.\n\n\n# Request will only authenticate if `SessionAuthentication` is in use.\nrequest = factory.get('/accounts/django-superstars/')\nrequest.user = user\nresponse = view(request)\n\n\n\n\n\nForcing CSRF validation\n\n\nBy default, requests created with \nAPIRequestFactory\n will not have CSRF validation applied when passed to a REST framework view. If you need to explicitly turn CSRF validation on, you can do so by setting the \nenforce_csrf_checks\n flag when instantiating the factory.\n\n\nfactory = APIRequestFactory(enforce_csrf_checks=True)\n\n\n\n\n\nNote\n: It's worth noting that Django's standard \nRequestFactory\n doesn't need to include this option, because when using regular Django the CSRF validation takes place in middleware, which is not run when testing views directly. When using REST framework, CSRF validation takes place inside the view, so the request factory needs to disable view-level CSRF checks.\n\n\n\n\nAPIClient\n\n\nExtends \nDjango's existing \nClient\n class\n.\n\n\nMaking requests\n\n\nThe \nAPIClient\n class supports the same request interface as Django's standard \nClient\n class. This means the that standard \n.get()\n, \n.post()\n, \n.put()\n, \n.patch()\n, \n.delete()\n, \n.head()\n and \n.options()\n methods are all available. For example:\n\n\nfrom rest_framework.test import APIClient\n\nclient = APIClient()\nclient.post('/notes/', {'title': 'new idea'}, format='json')\n\n\n\nTo support a wider set of request formats, or change the default format, \nsee the configuration section\n.\n\n\nAuthenticating\n\n\n.login(**kwargs)\n\n\nThe \nlogin\n method functions exactly as it does with Django's regular \nClient\n class. This allows you to authenticate requests against any views which include \nSessionAuthentication\n.\n\n\n# Make all requests in the context of a logged in session.\nclient = APIClient()\nclient.login(username='lauren', password='secret')\n\n\n\nTo logout, call the \nlogout\n method as usual.\n\n\n# Log out\nclient.logout()\n\n\n\nThe \nlogin\n method is appropriate for testing APIs that use session authentication, for example web sites which include AJAX interaction with the API.\n\n\n.credentials(**kwargs)\n\n\nThe \ncredentials\n method can be used to set headers that will then be included on all subsequent requests by the test client.\n\n\nfrom rest_framework.authtoken.models import Token\nfrom rest_framework.test import APIClient\n\n# Include an appropriate `Authorization:` header on all requests.\ntoken = Token.objects.get(user__username='lauren')\nclient = APIClient()\nclient.credentials(HTTP_AUTHORIZATION='Token ' + token.key)\n\n\n\nNote that calling \ncredentials\n a second time overwrites any existing credentials. You can unset any existing credentials by calling the method with no arguments.\n\n\n# Stop including any credentials\nclient.credentials()\n\n\n\nThe \ncredentials\n method is appropriate for testing APIs that require authentication headers, such as basic authentication, OAuth1a and OAuth2 authentication, and simple token authentication schemes.\n\n\n.force_authenticate(user=None, token=None)\n\n\nSometimes you may want to bypass authentication, and simple force all requests by the test client to be automatically treated as authenticated.\n\n\nThis can be a useful shortcut if you're testing the API but don't want to have to construct valid authentication credentials in order to make test requests.\n\n\nuser = User.objects.get(username='lauren')\nclient = APIClient()\nclient.force_authenticate(user=user)\n\n\n\nTo unauthenticate subsequent requests, call \nforce_authenticate\n setting the user and/or token to \nNone\n.\n\n\nclient.force_authenticate(user=None)\n\n\n\nCSRF validation\n\n\nBy default CSRF validation is not applied when using \nAPIClient\n. If you need to explicitly enable CSRF validation, you can do so by setting the \nenforce_csrf_checks\n flag when instantiating the client.\n\n\nclient = APIClient(enforce_csrf_checks=True)\n\n\n\nAs usual CSRF validation will only apply to any session authenticated views. This means CSRF validation will only occur if the client has been logged in by calling \nlogin()\n.\n\n\n\n\nRequestsClient\n\n\nREST framework also includes a client for interacting with your application\nusing the popular Python library, \nrequests\n.\n\n\nThis exposes exactly the same interface as if you were using a requests session\ndirectly.\n\n\nclient = RequestsClient()\nresponse = client.get('http://testserver/users/')\nassert response.status_code == 200\n\n\n\nNote that the requests client requires you to pass fully qualified URLs.\n\n\nHeaders \n Authentication\n\n\nCustom headers and authentication credentials can be provided in the same way\nas \nwhen using a standard \nrequests.Session\n instance\n.\n\n\nfrom requests.auth import HTTPBasicAuth\n\nclient.auth = HTTPBasicAuth('user', 'pass')\nclient.headers.update({'x-test': 'true'})\n\n\n\nCSRF\n\n\nIf you're using \nSessionAuthentication\n then you'll need to include a CSRF token\nfor any \nPOST\n, \nPUT\n, \nPATCH\n or \nDELETE\n requests.\n\n\nYou can do so by following the same flow that a JavaScript based client would use.\nFirst make a \nGET\n request in order to obtain a CRSF token, then present that\ntoken in the following request.\n\n\nFor example...\n\n\nclient = RequestsClient()\n\n# Obtain a CSRF token.\nresponse = client.get('/homepage/')\nassert response.status_code == 200\ncsrftoken = response.cookies['csrftoken']\n\n# Interact with the API.\nresponse = client.post('/organisations/', json={\n 'name': 'MegaCorp',\n 'status': 'active'\n}, headers={'X-CSRFToken': csrftoken})\nassert response.status_code == 200\n\n\n\nLive tests\n\n\nWith careful usage both the \nRequestsClient\n and the \nCoreAPIClient\n provide\nthe ability to write test cases that can run either in development, or be run\ndirectly against your staging server or production environment.\n\n\nUsing this style to create basic tests of a few core piece of functionality is\na powerful way to validate your live service. Doing so may require some careful\nattention to setup and teardown to ensure that the tests run in a way that they\ndo not directly affect customer data.\n\n\n\n\nCoreAPIClient\n\n\nThe CoreAPIClient allows you to interact with your API using the Python\n\ncoreapi\n client library.\n\n\n# Fetch the API schema\nclient = CoreAPIClient()\nschema = client.get('http://testserver/schema/')\n\n# Create a new organisation\nparams = {'name': 'MegaCorp', 'status': 'active'}\nclient.action(schema, ['organisations', 'create'], params)\n\n# Ensure that the organisation exists in the listing\ndata = client.action(schema, ['organisations', 'list'])\nassert(len(data) == 1)\nassert(data == [{'name': 'MegaCorp', 'status': 'active'}])\n\n\n\nHeaders \n Authentication\n\n\nCustom headers and authentication may be used with \nCoreAPIClient\n in a\nsimilar way as with \nRequestsClient\n.\n\n\nfrom requests.auth import HTTPBasicAuth\n\nclient = CoreAPIClient()\nclient.session.auth = HTTPBasicAuth('user', 'pass')\nclient.session.headers.update({'x-test': 'true'})\n\n\n\n\n\nTest cases\n\n\nREST framework includes the following test case classes, that mirror the existing Django test case classes, but use \nAPIClient\n instead of Django's default \nClient\n.\n\n\n\n\nAPISimpleTestCase\n\n\nAPITransactionTestCase\n\n\nAPITestCase\n\n\nAPILiveServerTestCase\n\n\n\n\nExample\n\n\nYou can use any of REST framework's test case classes as you would for the regular Django test case classes. The \nself.client\n attribute will be an \nAPIClient\n instance.\n\n\nfrom django.urls import reverse\nfrom rest_framework import status\nfrom rest_framework.test import APITestCase\nfrom myproject.apps.core.models import Account\n\nclass AccountTests(APITestCase):\n def test_create_account(self):\n \"\"\"\n Ensure we can create a new account object.\n \"\"\"\n url = reverse('account-list')\n data = {'name': 'DabApps'}\n response = self.client.post(url, data, format='json')\n self.assertEqual(response.status_code, status.HTTP_201_CREATED)\n self.assertEqual(Account.objects.count(), 1)\n self.assertEqual(Account.objects.get().name, 'DabApps')\n\n\n\n\n\nTesting responses\n\n\nChecking the response data\n\n\nWhen checking the validity of test responses it's often more convenient to inspect the data that the response was created with, rather than inspecting the fully rendered response.\n\n\nFor example, it's easier to inspect \nresponse.data\n:\n\n\nresponse = self.client.get('/users/4/')\nself.assertEqual(response.data, {'id': 4, 'username': 'lauren'})\n\n\n\nInstead of inspecting the result of parsing \nresponse.content\n:\n\n\nresponse = self.client.get('/users/4/')\nself.assertEqual(json.loads(response.content), {'id': 4, 'username': 'lauren'})\n\n\n\nRendering responses\n\n\nIf you're testing views directly using \nAPIRequestFactory\n, the responses that are returned will not yet be rendered, as rendering of template responses is performed by Django's internal request-response cycle. In order to access \nresponse.content\n, you'll first need to render the response.\n\n\nview = UserDetail.as_view()\nrequest = factory.get('/users/4')\nresponse = view(request, pk='4')\nresponse.render() # Cannot access `response.content` without this.\nself.assertEqual(response.content, '{\"username\": \"lauren\", \"id\": 4}')\n\n\n\n\n\nConfiguration\n\n\nSetting the default format\n\n\nThe default format used to make test requests may be set using the \nTEST_REQUEST_DEFAULT_FORMAT\n setting key. For example, to always use JSON for test requests by default instead of standard multipart form requests, set the following in your \nsettings.py\n file:\n\n\nREST_FRAMEWORK = {\n ...\n 'TEST_REQUEST_DEFAULT_FORMAT': 'json'\n}\n\n\n\nSetting the available formats\n\n\nIf you need to test requests using something other than multipart or json requests, you can do so by setting the \nTEST_REQUEST_RENDERER_CLASSES\n setting.\n\n\nFor example, to add support for using \nformat='html'\n in test requests, you might have something like this in your \nsettings.py\n file.\n\n\nREST_FRAMEWORK = {\n ...\n 'TEST_REQUEST_RENDERER_CLASSES': (\n 'rest_framework.renderers.MultiPartRenderer',\n 'rest_framework.renderers.JSONRenderer',\n 'rest_framework.renderers.TemplateHTMLRenderer'\n )\n}", + "text": "Testing\n\n\n\n\nCode without tests is broken as designed.\n\n\n \nJacob Kaplan-Moss\n\n\n\n\nREST framework includes a few helper classes that extend Django's existing test framework, and improve support for making API requests.\n\n\nAPIRequestFactory\n\n\nExtends \nDjango's existing \nRequestFactory\n class\n.\n\n\nCreating test requests\n\n\nThe \nAPIRequestFactory\n class supports an almost identical API to Django's standard \nRequestFactory\n class. This means that the standard \n.get()\n, \n.post()\n, \n.put()\n, \n.patch()\n, \n.delete()\n, \n.head()\n and \n.options()\n methods are all available.\n\n\nfrom rest_framework.test import APIRequestFactory\n\n# Using the standard RequestFactory API to create a form POST request\nfactory = APIRequestFactory()\nrequest = factory.post('/notes/', {'title': 'new idea'})\n\n\n\nUsing the \nformat\n argument\n\n\nMethods which create a request body, such as \npost\n, \nput\n and \npatch\n, include a \nformat\n argument, which make it easy to generate requests using a content type other than multipart form data. For example:\n\n\n# Create a JSON POST request\nfactory = APIRequestFactory()\nrequest = factory.post('/notes/', {'title': 'new idea'}, format='json')\n\n\n\nBy default the available formats are \n'multipart'\n and \n'json'\n. For compatibility with Django's existing \nRequestFactory\n the default format is \n'multipart'\n.\n\n\nTo support a wider set of request formats, or change the default format, \nsee the configuration section\n.\n\n\nExplicitly encoding the request body\n\n\nIf you need to explicitly encode the request body, you can do so by setting the \ncontent_type\n flag. For example:\n\n\nrequest = factory.post('/notes/', json.dumps({'title': 'new idea'}), content_type='application/json')\n\n\n\nPUT and PATCH with form data\n\n\nOne difference worth noting between Django's \nRequestFactory\n and REST framework's \nAPIRequestFactory\n is that multipart form data will be encoded for methods other than just \n.post()\n.\n\n\nFor example, using \nAPIRequestFactory\n, you can make a form PUT request like so:\n\n\nfactory = APIRequestFactory()\nrequest = factory.put('/notes/547/', {'title': 'remember to email dave'})\n\n\n\nUsing Django's \nRequestFactory\n, you'd need to explicitly encode the data yourself:\n\n\nfrom django.test.client import encode_multipart, RequestFactory\n\nfactory = RequestFactory()\ndata = {'title': 'remember to email dave'}\ncontent = encode_multipart('BoUnDaRyStRiNg', data)\ncontent_type = 'multipart/form-data; boundary=BoUnDaRyStRiNg'\nrequest = factory.put('/notes/547/', content, content_type=content_type)\n\n\n\nForcing authentication\n\n\nWhen testing views directly using a request factory, it's often convenient to be able to directly authenticate the request, rather than having to construct the correct authentication credentials.\n\n\nTo forcibly authenticate a request, use the \nforce_authenticate()\n method.\n\n\nfrom rest_framework.test import force_authenticate\n\nfactory = APIRequestFactory()\nuser = User.objects.get(username='olivia')\nview = AccountDetail.as_view()\n\n# Make an authenticated request to the view...\nrequest = factory.get('/accounts/django-superstars/')\nforce_authenticate(request, user=user)\nresponse = view(request)\n\n\n\nThe signature for the method is \nforce_authenticate(request, user=None, token=None)\n. When making the call, either or both of the user and token may be set.\n\n\nFor example, when forcibly authenticating using a token, you might do something like the following:\n\n\nuser = User.objects.get(username='olivia')\nrequest = factory.get('/accounts/django-superstars/')\nforce_authenticate(request, user=user, token=user.token)\n\n\n\n\n\nNote\n: When using \nAPIRequestFactory\n, the object that is returned is Django's standard \nHttpRequest\n, and not REST framework's \nRequest\n object, which is only generated once the view is called.\n\n\nThis means that setting attributes directly on the request object may not always have the effect you expect. For example, setting \n.token\n directly will have no effect, and setting \n.user\n directly will only work if session authentication is being used.\n\n\n# Request will only authenticate if `SessionAuthentication` is in use.\nrequest = factory.get('/accounts/django-superstars/')\nrequest.user = user\nresponse = view(request)\n\n\n\n\n\nForcing CSRF validation\n\n\nBy default, requests created with \nAPIRequestFactory\n will not have CSRF validation applied when passed to a REST framework view. If you need to explicitly turn CSRF validation on, you can do so by setting the \nenforce_csrf_checks\n flag when instantiating the factory.\n\n\nfactory = APIRequestFactory(enforce_csrf_checks=True)\n\n\n\n\n\nNote\n: It's worth noting that Django's standard \nRequestFactory\n doesn't need to include this option, because when using regular Django the CSRF validation takes place in middleware, which is not run when testing views directly. When using REST framework, CSRF validation takes place inside the view, so the request factory needs to disable view-level CSRF checks.\n\n\n\n\nAPIClient\n\n\nExtends \nDjango's existing \nClient\n class\n.\n\n\nMaking requests\n\n\nThe \nAPIClient\n class supports the same request interface as Django's standard \nClient\n class. This means the that standard \n.get()\n, \n.post()\n, \n.put()\n, \n.patch()\n, \n.delete()\n, \n.head()\n and \n.options()\n methods are all available. For example:\n\n\nfrom rest_framework.test import APIClient\n\nclient = APIClient()\nclient.post('/notes/', {'title': 'new idea'}, format='json')\n\n\n\nTo support a wider set of request formats, or change the default format, \nsee the configuration section\n.\n\n\nAuthenticating\n\n\n.login(**kwargs)\n\n\nThe \nlogin\n method functions exactly as it does with Django's regular \nClient\n class. This allows you to authenticate requests against any views which include \nSessionAuthentication\n.\n\n\n# Make all requests in the context of a logged in session.\nclient = APIClient()\nclient.login(username='lauren', password='secret')\n\n\n\nTo logout, call the \nlogout\n method as usual.\n\n\n# Log out\nclient.logout()\n\n\n\nThe \nlogin\n method is appropriate for testing APIs that use session authentication, for example web sites which include AJAX interaction with the API.\n\n\n.credentials(**kwargs)\n\n\nThe \ncredentials\n method can be used to set headers that will then be included on all subsequent requests by the test client.\n\n\nfrom rest_framework.authtoken.models import Token\nfrom rest_framework.test import APIClient\n\n# Include an appropriate `Authorization:` header on all requests.\ntoken = Token.objects.get(user__username='lauren')\nclient = APIClient()\nclient.credentials(HTTP_AUTHORIZATION='Token ' + token.key)\n\n\n\nNote that calling \ncredentials\n a second time overwrites any existing credentials. You can unset any existing credentials by calling the method with no arguments.\n\n\n# Stop including any credentials\nclient.credentials()\n\n\n\nThe \ncredentials\n method is appropriate for testing APIs that require authentication headers, such as basic authentication, OAuth1a and OAuth2 authentication, and simple token authentication schemes.\n\n\n.force_authenticate(user=None, token=None)\n\n\nSometimes you may want to bypass authentication, and simple force all requests by the test client to be automatically treated as authenticated.\n\n\nThis can be a useful shortcut if you're testing the API but don't want to have to construct valid authentication credentials in order to make test requests.\n\n\nuser = User.objects.get(username='lauren')\nclient = APIClient()\nclient.force_authenticate(user=user)\n\n\n\nTo unauthenticate subsequent requests, call \nforce_authenticate\n setting the user and/or token to \nNone\n.\n\n\nclient.force_authenticate(user=None)\n\n\n\nCSRF validation\n\n\nBy default CSRF validation is not applied when using \nAPIClient\n. If you need to explicitly enable CSRF validation, you can do so by setting the \nenforce_csrf_checks\n flag when instantiating the client.\n\n\nclient = APIClient(enforce_csrf_checks=True)\n\n\n\nAs usual CSRF validation will only apply to any session authenticated views. This means CSRF validation will only occur if the client has been logged in by calling \nlogin()\n.\n\n\n\n\nRequestsClient\n\n\nREST framework also includes a client for interacting with your application\nusing the popular Python library, \nrequests\n. This may be useful if:\n\n\n\n\nYou are expecting to interface with the API primarily from another Python service,\nand want to test the service at the same level as the client will see.\n\n\nYou want to write tests in such a way that they can also be run against a staging or\nlive environment. (See \"Live tests\" below.)\n\n\n\n\nThis exposes exactly the same interface as if you were using a requests session\ndirectly.\n\n\nclient = RequestsClient()\nresponse = client.get('http://testserver/users/')\nassert response.status_code == 200\n\n\n\nNote that the requests client requires you to pass fully qualified URLs.\n\n\nRequestsClient\n and working with the database\n\n\nThe \nRequestsClient\n class is useful if\n\n\nHeaders \n Authentication\n\n\nCustom headers and authentication credentials can be provided in the same way\nas \nwhen using a standard \nrequests.Session\n instance\n.\n\n\nfrom requests.auth import HTTPBasicAuth\n\nclient.auth = HTTPBasicAuth('user', 'pass')\nclient.headers.update({'x-test': 'true'})\n\n\n\nCSRF\n\n\nIf you're using \nSessionAuthentication\n then you'll need to include a CSRF token\nfor any \nPOST\n, \nPUT\n, \nPATCH\n or \nDELETE\n requests.\n\n\nYou can do so by following the same flow that a JavaScript based client would use.\nFirst make a \nGET\n request in order to obtain a CRSF token, then present that\ntoken in the following request.\n\n\nFor example...\n\n\nclient = RequestsClient()\n\n# Obtain a CSRF token.\nresponse = client.get('/homepage/')\nassert response.status_code == 200\ncsrftoken = response.cookies['csrftoken']\n\n# Interact with the API.\nresponse = client.post('/organisations/', json={\n 'name': 'MegaCorp',\n 'status': 'active'\n}, headers={'X-CSRFToken': csrftoken})\nassert response.status_code == 200\n\n\n\nLive tests\n\n\nWith careful usage both the \nRequestsClient\n and the \nCoreAPIClient\n provide\nthe ability to write test cases that can run either in development, or be run\ndirectly against your staging server or production environment.\n\n\nUsing this style to create basic tests of a few core piece of functionality is\na powerful way to validate your live service. Doing so may require some careful\nattention to setup and teardown to ensure that the tests run in a way that they\ndo not directly affect customer data.\n\n\n\n\nCoreAPIClient\n\n\nThe CoreAPIClient allows you to interact with your API using the Python\n\ncoreapi\n client library.\n\n\n# Fetch the API schema\nclient = CoreAPIClient()\nschema = client.get('http://testserver/schema/')\n\n# Create a new organisation\nparams = {'name': 'MegaCorp', 'status': 'active'}\nclient.action(schema, ['organisations', 'create'], params)\n\n# Ensure that the organisation exists in the listing\ndata = client.action(schema, ['organisations', 'list'])\nassert(len(data) == 1)\nassert(data == [{'name': 'MegaCorp', 'status': 'active'}])\n\n\n\nHeaders \n Authentication\n\n\nCustom headers and authentication may be used with \nCoreAPIClient\n in a\nsimilar way as with \nRequestsClient\n.\n\n\nfrom requests.auth import HTTPBasicAuth\n\nclient = CoreAPIClient()\nclient.session.auth = HTTPBasicAuth('user', 'pass')\nclient.session.headers.update({'x-test': 'true'})\n\n\n\n\n\nTest cases\n\n\nREST framework includes the following test case classes, that mirror the existing Django test case classes, but use \nAPIClient\n instead of Django's default \nClient\n.\n\n\n\n\nAPISimpleTestCase\n\n\nAPITransactionTestCase\n\n\nAPITestCase\n\n\nAPILiveServerTestCase\n\n\n\n\nExample\n\n\nYou can use any of REST framework's test case classes as you would for the regular Django test case classes. The \nself.client\n attribute will be an \nAPIClient\n instance.\n\n\nfrom django.urls import reverse\nfrom rest_framework import status\nfrom rest_framework.test import APITestCase\nfrom myproject.apps.core.models import Account\n\nclass AccountTests(APITestCase):\n def test_create_account(self):\n \"\"\"\n Ensure we can create a new account object.\n \"\"\"\n url = reverse('account-list')\n data = {'name': 'DabApps'}\n response = self.client.post(url, data, format='json')\n self.assertEqual(response.status_code, status.HTTP_201_CREATED)\n self.assertEqual(Account.objects.count(), 1)\n self.assertEqual(Account.objects.get().name, 'DabApps')\n\n\n\n\n\nTesting responses\n\n\nChecking the response data\n\n\nWhen checking the validity of test responses it's often more convenient to inspect the data that the response was created with, rather than inspecting the fully rendered response.\n\n\nFor example, it's easier to inspect \nresponse.data\n:\n\n\nresponse = self.client.get('/users/4/')\nself.assertEqual(response.data, {'id': 4, 'username': 'lauren'})\n\n\n\nInstead of inspecting the result of parsing \nresponse.content\n:\n\n\nresponse = self.client.get('/users/4/')\nself.assertEqual(json.loads(response.content), {'id': 4, 'username': 'lauren'})\n\n\n\nRendering responses\n\n\nIf you're testing views directly using \nAPIRequestFactory\n, the responses that are returned will not yet be rendered, as rendering of template responses is performed by Django's internal request-response cycle. In order to access \nresponse.content\n, you'll first need to render the response.\n\n\nview = UserDetail.as_view()\nrequest = factory.get('/users/4')\nresponse = view(request, pk='4')\nresponse.render() # Cannot access `response.content` without this.\nself.assertEqual(response.content, '{\"username\": \"lauren\", \"id\": 4}')\n\n\n\n\n\nConfiguration\n\n\nSetting the default format\n\n\nThe default format used to make test requests may be set using the \nTEST_REQUEST_DEFAULT_FORMAT\n setting key. For example, to always use JSON for test requests by default instead of standard multipart form requests, set the following in your \nsettings.py\n file:\n\n\nREST_FRAMEWORK = {\n ...\n 'TEST_REQUEST_DEFAULT_FORMAT': 'json'\n}\n\n\n\nSetting the available formats\n\n\nIf you need to test requests using something other than multipart or json requests, you can do so by setting the \nTEST_REQUEST_RENDERER_CLASSES\n setting.\n\n\nFor example, to add support for using \nformat='html'\n in test requests, you might have something like this in your \nsettings.py\n file.\n\n\nREST_FRAMEWORK = {\n ...\n 'TEST_REQUEST_RENDERER_CLASSES': (\n 'rest_framework.renderers.MultiPartRenderer',\n 'rest_framework.renderers.JSONRenderer',\n 'rest_framework.renderers.TemplateHTMLRenderer'\n )\n}", "title": "Testing" }, { @@ -3492,9 +3492,14 @@ }, { "location": "/api-guide/testing/#requestsclient", - "text": "REST framework also includes a client for interacting with your application\nusing the popular Python library, requests . This exposes exactly the same interface as if you were using a requests session\ndirectly. client = RequestsClient()\nresponse = client.get('http://testserver/users/')\nassert response.status_code == 200 Note that the requests client requires you to pass fully qualified URLs.", + "text": "REST framework also includes a client for interacting with your application\nusing the popular Python library, requests . This may be useful if: You are expecting to interface with the API primarily from another Python service,\nand want to test the service at the same level as the client will see. You want to write tests in such a way that they can also be run against a staging or\nlive environment. (See \"Live tests\" below.) This exposes exactly the same interface as if you were using a requests session\ndirectly. client = RequestsClient()\nresponse = client.get('http://testserver/users/')\nassert response.status_code == 200 Note that the requests client requires you to pass fully qualified URLs.", "title": "RequestsClient" }, + { + "location": "/api-guide/testing/#requestsclient-and-working-with-the-database", + "text": "The RequestsClient class is useful if", + "title": "RequestsClient and working with the database" + }, { "location": "/api-guide/testing/#headers-authentication", "text": "Custom headers and authentication credentials can be provided in the same way\nas when using a standard requests.Session instance . from requests.auth import HTTPBasicAuth\n\nclient.auth = HTTPBasicAuth('user', 'pass')\nclient.headers.update({'x-test': 'true'})", diff --git a/sitemap.xml b/sitemap.xml index ca5010c66..24dc595af 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -4,7 +4,7 @@ http://www.django-rest-framework.org// - 2016-11-07 + 2016-12-09 daily @@ -13,49 +13,49 @@ http://www.django-rest-framework.org//tutorial/quickstart/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/1-serialization/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/2-requests-and-responses/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/3-class-based-views/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/4-authentication-and-permissions/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/5-relationships-and-hyperlinked-apis/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/6-viewsets-and-routers/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//tutorial/7-schemas-and-client-libraries/ - 2016-11-07 + 2016-12-09 daily @@ -65,163 +65,163 @@ http://www.django-rest-framework.org//api-guide/requests/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/responses/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/views/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/generic-views/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/viewsets/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/routers/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/parsers/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/renderers/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/serializers/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/fields/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/relations/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/validators/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/authentication/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/permissions/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/throttling/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/filtering/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/pagination/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/versioning/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/content-negotiation/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/metadata/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/schemas/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/format-suffixes/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/reverse/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/exceptions/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/status-codes/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/testing/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//api-guide/settings/ - 2016-11-07 + 2016-12-09 daily @@ -231,127 +231,127 @@ http://www.django-rest-framework.org//topics/documenting-your-api/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/api-clients/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/internationalization/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/ajax-csrf-cors/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/html-and-forms/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/browser-enhancements/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/browsable-api/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/rest-hypermedia-hateoas/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/third-party-resources/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/contributing/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/project-management/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/3.0-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/3.1-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/3.2-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/3.3-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/3.4-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/3.5-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/kickstarter-announcement/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/mozilla-grant/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/funding/ - 2016-11-07 + 2016-12-09 daily http://www.django-rest-framework.org//topics/release-notes/ - 2016-11-07 + 2016-12-09 daily diff --git a/topics/3.0-announcement/index.html b/topics/3.0-announcement/index.html index 26af42476..239e2e5be 100644 --- a/topics/3.0-announcement/index.html +++ b/topics/3.0-announcement/index.html @@ -1098,7 +1098,7 @@ class OrganizationSerializer(serializers.Serializer): }

    File fields as URLs

    -

    The FileField and ImageField classes are now represented as URLs by default. You should ensure you set Django's standard MEDIA_URL setting appropriately, and ensure your application serves the uploaded files.

    +

    The FileField and ImageField classes are now represented as URLs by default. You should ensure you set Django's standard MEDIA_URL setting appropriately, and ensure your application serves the uploaded files.

    You can revert this behavior, and display filenames in the representation by using the UPLOADED_FILES_USE_URL settings key:

    REST_FRAMEWORK = {
         'UPLOADED_FILES_USE_URL': False
    @@ -1150,7 +1150,7 @@ amount = serializers.DecimalField(
     
    • The serializer ChoiceField does not currently display nested choices, as was the case in 2.4. This will be address as part of 3.1.
    • Due to the new templated form rendering, the 'widget' option is no longer valid. This means there's no easy way of using third party "autocomplete" widgets for rendering select inputs that contain a large number of choices. You'll either need to use a regular select or a plain text input. We may consider addressing this in 3.1 or 3.2 if there's sufficient demand.
    • -
    • Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still create language files with Django if you wish to localize them.
    • +
    • Some of the default validation error messages were rewritten and might no longer be pre-translated. You can still create language files with Django if you wish to localize them.
    • APIException subclasses could previously take any arbitrary type in the detail argument. These exceptions now use translatable text strings, and as a result call force_text on the detail argument, which must be a string. If you need complex arguments to an APIException class, you should subclass it and override the __init__() method. Typically you'll instead want to use a custom exception handler to provide for non-standard error responses.

    diff --git a/topics/ajax-csrf-cors/index.html b/topics/ajax-csrf-cors/index.html index bd2f41a5d..84c20ecf2 100644 --- a/topics/ajax-csrf-cors/index.html +++ b/topics/ajax-csrf-cors/index.html @@ -414,7 +414,7 @@
  • Ensure that any 'unsafe' HTTP operations, such as POST, PUT, PATCH and DELETE, always require a valid CSRF token.
  • If you're using SessionAuthentication you'll need to include valid CSRF tokens for any POST, PUT, PATCH or DELETE operations.

    -

    In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.

    +

    In order to make AJAX requests, you need to include CSRF token in the HTTP header, as described in the Django documentation.

    CORS

    Cross-Origin Resource Sharing is a mechanism for allowing clients to interact with APIs that are hosted on a different domain. CORS works by requiring the server to include a specific set of headers that allow a browser to determine if and when cross-domain requests should be allowed.

    The best way to deal with CORS in REST framework is to add the required response headers in middleware. This ensures that CORS is supported transparently, without having to change any behavior in your views.

    diff --git a/topics/release-notes/index.html b/topics/release-notes/index.html index 93dca42e6..b2b1991b3 100644 --- a/topics/release-notes/index.html +++ b/topics/release-notes/index.html @@ -431,7 +431,7 @@

    Medium version numbers (0.x.0) may include API changes, in line with the deprecation policy. You should read the release notes carefully before upgrading between medium point releases.

    Major version numbers (x.0.0) are reserved for substantial project milestones.

    Deprecation policy

    -

    REST framework releases follow a formal deprecation policy, which is in line with Django's deprecation policy.

    +

    REST framework releases follow a formal deprecation policy, which is in line with Django's deprecation policy.

    The timeline for deprecation of a feature present in version 1.0 would work as follows:

    • diff --git a/tutorial/quickstart/index.html b/tutorial/quickstart/index.html index b804b06aa..b42f14f6f 100644 --- a/tutorial/quickstart/index.html +++ b/tutorial/quickstart/index.html @@ -508,7 +508,9 @@ urlpatterns = [ ) REST_FRAMEWORK = { - 'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',), + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.IsAdminUser', + ], 'PAGE_SIZE': 10 }