mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-26 11:33:59 +03:00
Replace "class based views" occurrences with "class-based views" (#4251)
This commit is contained in:
parent
7c171dfd83
commit
ff5cfe3e84
|
@ -44,7 +44,7 @@ The default authentication schemes may be set globally, using the `DEFAULT_AUTHE
|
||||||
}
|
}
|
||||||
|
|
||||||
You can also set the authentication scheme on a per-view or per-viewset basis,
|
You can also set the authentication scheme on a per-view or per-viewset basis,
|
||||||
using the `APIView` class based views.
|
using the `APIView` class-based views.
|
||||||
|
|
||||||
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
|
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
|
|
@ -77,7 +77,7 @@ The default content negotiation class may be set globally, using the `DEFAULT_CO
|
||||||
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.IgnoreClientContentNegotiation',
|
'DEFAULT_CONTENT_NEGOTIATION_CLASS': 'myapp.negotiation.IgnoreClientContentNegotiation',
|
||||||
}
|
}
|
||||||
|
|
||||||
You can also set the content negotiation used for an individual view, or viewset, using the `APIView` class based views.
|
You can also set the content negotiation used for an individual view, or viewset, using the `APIView` class-based views.
|
||||||
|
|
||||||
from myapp.negotiation import IgnoreClientContentNegotiation
|
from myapp.negotiation import IgnoreClientContentNegotiation
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
|
@ -96,7 +96,7 @@ The default filter backends may be set globally, using the `DEFAULT_FILTER_BACKE
|
||||||
}
|
}
|
||||||
|
|
||||||
You can also set the filter backends on a per-view, or per-viewset basis,
|
You can also set the filter backends on a per-view, or per-viewset basis,
|
||||||
using the `GenericAPIView` class based views.
|
using the `GenericAPIView` class-based views.
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from myapp.serializers import UserSerializer
|
from myapp.serializers import UserSerializer
|
||||||
|
|
|
@ -42,7 +42,7 @@ When using `format_suffix_patterns`, you must make sure to add the `'format'` ke
|
||||||
def comment_list(request, format=None):
|
def comment_list(request, format=None):
|
||||||
# do stuff...
|
# do stuff...
|
||||||
|
|
||||||
Or with class based views:
|
Or with class-based views:
|
||||||
|
|
||||||
class CommentList(APIView):
|
class CommentList(APIView):
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
|
|
|
@ -7,7 +7,7 @@ source: mixins.py
|
||||||
>
|
>
|
||||||
> — [Django Documentation][cite]
|
> — [Django Documentation][cite]
|
||||||
|
|
||||||
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.
|
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.
|
The generic views provided by REST framework allow you to quickly build API views that map closely to your database models.
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSE
|
||||||
}
|
}
|
||||||
|
|
||||||
You can also set the parsers used for an individual view, or viewset,
|
You can also set the parsers used for an individual view, or viewset,
|
||||||
using the `APIView` class based views.
|
using the `APIView` class-based views.
|
||||||
|
|
||||||
from rest_framework.parsers import JSONParser
|
from rest_framework.parsers import JSONParser
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
|
@ -71,7 +71,7 @@ If not specified, this setting defaults to allowing unrestricted access:
|
||||||
)
|
)
|
||||||
|
|
||||||
You can also set the authentication policy on a per-view, or per-viewset basis,
|
You can also set the authentication policy on a per-view, or per-viewset basis,
|
||||||
using the `APIView` class based views.
|
using the `APIView` class-based views.
|
||||||
|
|
||||||
from rest_framework.permissions import IsAuthenticated
|
from rest_framework.permissions import IsAuthenticated
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
|
@ -28,7 +28,7 @@ The default set of renderers may be set globally, using the `DEFAULT_RENDERER_CL
|
||||||
}
|
}
|
||||||
|
|
||||||
You can also set the renderers used for an individual view, or viewset,
|
You can also set the renderers used for an individual view, or viewset,
|
||||||
using the `APIView` class based views.
|
using the `APIView` class-based views.
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from rest_framework.renderers import JSONRenderer
|
from rest_framework.renderers import JSONRenderer
|
||||||
|
|
|
@ -876,7 +876,7 @@ There are four methods that can be overridden, depending on what functionality y
|
||||||
* `.to_internal_value()` - Override this to support deserialization, for write operations.
|
* `.to_internal_value()` - Override this to support deserialization, for write operations.
|
||||||
* `.create()` and `.update()` - Override either or both of these to support saving instances.
|
* `.create()` and `.update()` - Override either or both of these to support saving instances.
|
||||||
|
|
||||||
Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class based views exactly as you would for a regular `Serializer` or `ModelSerializer`.
|
Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class-based views exactly as you would for a regular `Serializer` or `ModelSerializer`.
|
||||||
|
|
||||||
The only difference you'll notice when doing so is the `BaseSerializer` classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.
|
The only difference you'll notice when doing so is the `BaseSerializer` classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ The `api_settings` object will check for any user-defined settings, and otherwis
|
||||||
|
|
||||||
## API policy settings
|
## API policy settings
|
||||||
|
|
||||||
*The following settings control the basic API policies, and are applied to every `APIView` class based view, or `@api_view` function based view.*
|
*The following settings control the basic API policies, and are applied to every `APIView` class-based view, or `@api_view` function based view.*
|
||||||
|
|
||||||
#### DEFAULT_RENDERER_CLASSES
|
#### DEFAULT_RENDERER_CLASSES
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ Default: `'rest_framework.negotiation.DefaultContentNegotiation'`
|
||||||
|
|
||||||
## Generic view settings
|
## Generic view settings
|
||||||
|
|
||||||
*The following settings control the behavior of the generic class based views.*
|
*The following settings control the behavior of the generic class-based views.*
|
||||||
|
|
||||||
#### DEFAULT_PAGINATION_SERIALIZER_CLASS
|
#### DEFAULT_PAGINATION_SERIALIZER_CLASS
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ The default throttling policy may be set globally, using the `DEFAULT_THROTTLE_C
|
||||||
The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `minute`, `hour` or `day` as the throttle period.
|
The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `minute`, `hour` or `day` as the throttle period.
|
||||||
|
|
||||||
You can also set the throttling policy on a per-view or per-viewset basis,
|
You can also set the throttling policy on a per-view or per-viewset basis,
|
||||||
using the `APIView` class based views.
|
using the `APIView` class-based views.
|
||||||
|
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.throttling import UserRateThrottle
|
from rest_framework.throttling import UserRateThrottle
|
||||||
|
|
|
@ -265,9 +265,9 @@ A validator may be any callable that raises a `serializers.ValidationError` on f
|
||||||
if value % 2 != 0:
|
if value % 2 != 0:
|
||||||
raise serializers.ValidationError('This field must be an even number.')
|
raise serializers.ValidationError('This field must be an even number.')
|
||||||
|
|
||||||
## Class based
|
## Class-based
|
||||||
|
|
||||||
To write a class based validator, use the `__call__` method. Class based validators are useful as they allow you to parameterize and reuse behavior.
|
To write a class-based validator, use the `__call__` method. Class-based validators are useful as they allow you to parameterize and reuse behavior.
|
||||||
|
|
||||||
class MultipleOf(object):
|
class MultipleOf(object):
|
||||||
def __init__(self, base):
|
def __init__(self, base):
|
||||||
|
@ -280,7 +280,7 @@ To write a class based validator, use the `__call__` method. Class based validat
|
||||||
|
|
||||||
#### Using `set_context()`
|
#### Using `set_context()`
|
||||||
|
|
||||||
In 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 `set_context` method on a class based validator.
|
In 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 `set_context` method on a class-based validator.
|
||||||
|
|
||||||
def set_context(self, serializer_field):
|
def set_context(self, serializer_field):
|
||||||
# Determine if this is an update or a create operation.
|
# Determine if this is an update or a create operation.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
source: decorators.py
|
source: decorators.py
|
||||||
views.py
|
views.py
|
||||||
|
|
||||||
# Class Based Views
|
# Class-based Views
|
||||||
|
|
||||||
> Django's class based views are a welcome departure from the old-style views.
|
> Django's class-based views are a welcome departure from the old-style views.
|
||||||
>
|
>
|
||||||
> — [Reinout van Rees][cite]
|
> — [Reinout van Rees][cite]
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ You won't typically need to override this method.
|
||||||
|
|
||||||
# Function Based Views
|
# Function Based Views
|
||||||
|
|
||||||
> Saying [that Class based views] is always the superior solution is a mistake.
|
> Saying [that class-based views] is always the superior solution is a mistake.
|
||||||
>
|
>
|
||||||
> — [Nick Coghlan][cite2]
|
> — [Nick Coghlan][cite2]
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ The tutorial will walk you through the building blocks that make up REST framewo
|
||||||
|
|
||||||
* [1 - Serialization][tut-1]
|
* [1 - Serialization][tut-1]
|
||||||
* [2 - Requests & Responses][tut-2]
|
* [2 - Requests & Responses][tut-2]
|
||||||
* [3 - Class based views][tut-3]
|
* [3 - Class-based views][tut-3]
|
||||||
* [4 - Authentication & permissions][tut-4]
|
* [4 - Authentication & permissions][tut-4]
|
||||||
* [5 - Relationships & hyperlinked APIs][tut-5]
|
* [5 - Relationships & hyperlinked APIs][tut-5]
|
||||||
* [6 - Viewsets & routers][tut-6]
|
* [6 - Viewsets & routers][tut-6]
|
||||||
|
|
|
@ -6,7 +6,7 @@ REST framework 2.3 makes it even quicker and easier to build your Web APIs.
|
||||||
|
|
||||||
The 2.3 release introduces the [ViewSet][viewset] and [Router][router] classes.
|
The 2.3 release introduces the [ViewSet][viewset] and [Router][router] classes.
|
||||||
|
|
||||||
A viewset is simply a type of class based view that allows you to group multiple views into a single common class.
|
A viewset is simply a type of class-based view that allows you to group multiple views into a single common class.
|
||||||
|
|
||||||
Routers allow you to automatically determine the URLconf for your viewset classes.
|
Routers allow you to automatically determine the URLconf for your viewset classes.
|
||||||
|
|
||||||
|
|
|
@ -426,7 +426,7 @@ There are four methods that can be overridden, depending on what functionality y
|
||||||
* `.to_internal_value()` - Override this to support deserialization, for write operations.
|
* `.to_internal_value()` - Override this to support deserialization, for write operations.
|
||||||
* `.create()` and `.update()` - Override either or both of these to support saving instances.
|
* `.create()` and `.update()` - Override either or both of these to support saving instances.
|
||||||
|
|
||||||
Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class based views exactly as you would for a regular `Serializer` or `ModelSerializer`.
|
Because this class provides the same interface as the `Serializer` class, you can use it with the existing generic class-based views exactly as you would for a regular `Serializer` or `ModelSerializer`.
|
||||||
|
|
||||||
The only difference you'll notice when doing so is the `BaseSerializer` classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.
|
The only difference you'll notice when doing so is the `BaseSerializer` classes will not generate HTML forms in the browsable API. This is because the data they return does not include all the field information that would allow each field to be rendered into a suitable HTML input.
|
||||||
|
|
||||||
|
@ -801,7 +801,7 @@ This change means that you can now easily customize the style of error responses
|
||||||
|
|
||||||
## The metadata API
|
## The metadata API
|
||||||
|
|
||||||
Behavior for dealing with `OPTIONS` requests was previously built directly into the class based views. This has now been properly separated out into a Metadata API that allows the same pluggable style as other API policies in REST framework.
|
Behavior for dealing with `OPTIONS` requests was previously built directly into the class-based views. This has now been properly separated out into a Metadata API that allows the same pluggable style as other API policies in REST framework.
|
||||||
|
|
||||||
This makes it far easier to use a different style for `OPTIONS` responses throughout your API, and makes it possible to create third-party metadata policies.
|
This makes it far easier to use a different style for `OPTIONS` responses throughout your API, and makes it possible to create third-party metadata policies.
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ Using numeric HTTP status codes in your views doesn't always make for obvious re
|
||||||
REST framework provides two wrappers you can use to write API views.
|
REST framework provides two wrappers you can use to write API views.
|
||||||
|
|
||||||
1. The `@api_view` decorator for working with function based views.
|
1. The `@api_view` decorator for working with function based views.
|
||||||
2. The `APIView` class for working with class based views.
|
2. The `APIView` class for working with class-based views.
|
||||||
|
|
||||||
These wrappers provide a few bits of functionality such as making sure you receive `Request` instances in your view, and adding context to `Response` objects so that content negotiation can be performed.
|
These wrappers provide a few bits of functionality such as making sure you receive `Request` instances in your view, and adding context to `Response` objects so that content negotiation can be performed.
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ See the [browsable api][browsable-api] topic for more information about the brow
|
||||||
|
|
||||||
## What's next?
|
## What's next?
|
||||||
|
|
||||||
In [tutorial part 3][tut-3], we'll start using class based views, and see how generic views reduce the amount of code we need to write.
|
In [tutorial part 3][tut-3], we'll start using class-based views, and see how generic views reduce the amount of code we need to write.
|
||||||
|
|
||||||
[json-url]: http://example.com/api/items/4/.json
|
[json-url]: http://example.com/api/items/4/.json
|
||||||
[devserver]: http://127.0.0.1:8000/snippets/
|
[devserver]: http://127.0.0.1:8000/snippets/
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# Tutorial 3: Class Based Views
|
# Tutorial 3: Class-based Views
|
||||||
|
|
||||||
We can also write our API views using class based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code [DRY][dry].
|
We can also write our API views using class-based views, rather than function based views. As we'll see this is a powerful pattern that allows us to reuse common functionality, and helps us keep our code [DRY][dry].
|
||||||
|
|
||||||
## Rewriting our API using class based views
|
## Rewriting our API using class-based views
|
||||||
|
|
||||||
We'll start by rewriting the root view as a class based view. All this involves is a little bit of refactoring of `views.py`.
|
We'll start by rewriting the root view as a class-based view. All this involves is a little bit of refactoring of `views.py`.
|
||||||
|
|
||||||
from snippets.models import Snippet
|
from snippets.models import Snippet
|
||||||
from snippets.serializers import SnippetSerializer
|
from snippets.serializers import SnippetSerializer
|
||||||
|
@ -62,7 +62,7 @@ So far, so good. It looks pretty similar to the previous case, but we've got be
|
||||||
|
|
||||||
That's looking good. Again, it's still pretty similar to the function based view right now.
|
That's looking good. Again, it's still pretty similar to the function based view right now.
|
||||||
|
|
||||||
We'll also need to refactor our `urls.py` slightly now we're using class based views.
|
We'll also need to refactor our `urls.py` slightly now we're using class-based views.
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from rest_framework.urlpatterns import format_suffix_patterns
|
from rest_framework.urlpatterns import format_suffix_patterns
|
||||||
|
@ -79,7 +79,7 @@ Okay, we're done. If you run the development server everything should be workin
|
||||||
|
|
||||||
## Using mixins
|
## Using mixins
|
||||||
|
|
||||||
One of the big wins of using class based views is that it allows us to easily compose reusable bits of behaviour.
|
One of the big wins of using class-based views is that it allows us to easily compose reusable bits of behaviour.
|
||||||
|
|
||||||
The create/retrieve/update/delete operations that we've been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.
|
The create/retrieve/update/delete operations that we've been using so far are going to be pretty similar for any model-backed API views we create. Those bits of common behaviour are implemented in REST framework's mixin classes.
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ The base class provides the core functionality, and the mixin classes provide th
|
||||||
|
|
||||||
Pretty similar. Again we're using the `GenericAPIView` class to provide the core functionality, and adding in mixins to provide the `.retrieve()`, `.update()` and `.destroy()` actions.
|
Pretty similar. Again we're using the `GenericAPIView` class to provide the core functionality, and adding in mixins to provide the `.retrieve()`, `.update()` and `.destroy()` actions.
|
||||||
|
|
||||||
## Using generic class based views
|
## Using generic class-based views
|
||||||
|
|
||||||
Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use to trim down our `views.py` module even more.
|
Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use to trim down our `views.py` module even more.
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ Now that we've got some users to work with, we'd better add representations of t
|
||||||
|
|
||||||
Because `'snippets'` is a *reverse* relationship on the User model, it will not be included by default when using the `ModelSerializer` class, so we needed to add an explicit field for it.
|
Because `'snippets'` is a *reverse* relationship on the User model, it will not be included by default when using the `ModelSerializer` class, so we needed to add an explicit field for it.
|
||||||
|
|
||||||
We'll also add a couple of views to `views.py`. We'd like to just use read-only views for the user representations, so we'll use the `ListAPIView` and `RetrieveAPIView` generic class based views.
|
We'll also add a couple of views to `views.py`. We'd like to just use read-only views for the user representations, so we'll use the `ListAPIView` and `RetrieveAPIView` generic class-based views.
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ Okay, now let's wire up the API URLs. On to `tutorial/urls.py`...
|
||||||
|
|
||||||
Because 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.
|
Because 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.
|
||||||
|
|
||||||
Again, 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.
|
Again, 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.
|
||||||
|
|
||||||
Finally, 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.
|
Finally, 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.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user