mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 17:47:04 +03:00
Include import paths throughout docs.
Closes #1051. Thanks to @pydanny for the report.
This commit is contained in:
parent
f84d4951bf
commit
5e40e50f2b
|
@ -46,6 +46,11 @@ 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,
|
||||
using the `APIView` class based views.
|
||||
|
||||
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class ExampleView(APIView):
|
||||
authentication_classes = (SessionAuthentication, BasicAuthentication)
|
||||
permission_classes = (IsAuthenticated,)
|
||||
|
@ -157,11 +162,16 @@ The `curl` command line tool may be useful for testing token authenticated APIs.
|
|||
|
||||
If you want every user to have an automatically generated Token, you can simply catch the User's `post_save` signal.
|
||||
|
||||
from django.dispatch import receiver
|
||||
from rest_framework.authtoken.models import Token
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def create_auth_token(sender, instance=None, created=False, **kwargs):
|
||||
if created:
|
||||
Token.objects.create(user=instance)
|
||||
|
||||
Note that you'll want to ensure you place this code snippet in an installed `models.py` module, or some other location that will be imported by Django on startup.
|
||||
|
||||
If you've already created some users, you can generate tokens for all existing users like this:
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
@ -336,6 +346,10 @@ If the `.authenticate_header()` method is not overridden, the authentication sch
|
|||
|
||||
The following example will authenticate any incoming request as the user given by the username in a custom request header named 'X_USERNAME'.
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import authentication
|
||||
from rest_framework import exceptions
|
||||
|
||||
class ExampleAuthentication(authentication.BaseAuthentication):
|
||||
def authenticate(self, request):
|
||||
username = request.META.get('X_USERNAME')
|
||||
|
|
|
@ -54,6 +54,8 @@ The `select_renderer()` method should return a two-tuple of (renderer instance,
|
|||
The following is a custom content negotiation class which ignores the client
|
||||
request when selecting the appropriate parser or renderer.
|
||||
|
||||
from rest_framework.negotiation import BaseContentNegotiation
|
||||
|
||||
class IgnoreClientContentNegotiation(BaseContentNegotiation):
|
||||
def select_parser(self, request, parsers):
|
||||
"""
|
||||
|
@ -77,6 +79,10 @@ The default content negotiation class may be set globally, using the `DEFAULT_CO
|
|||
|
||||
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 rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class NoNegotiationView(APIView):
|
||||
"""
|
||||
An example view that does not perform content negotiation.
|
||||
|
|
|
@ -78,6 +78,9 @@ A generic, **read-only** field. You can use this field for any attribute that d
|
|||
|
||||
For example, using the following model.
|
||||
|
||||
from django.db import models
|
||||
from django.utils.timezone import now
|
||||
|
||||
class Account(models.Model):
|
||||
owner = models.ForeignKey('auth.user')
|
||||
name = models.CharField(max_length=100)
|
||||
|
@ -85,13 +88,14 @@ For example, using the following model.
|
|||
payment_expiry = models.DateTimeField()
|
||||
|
||||
def has_expired(self):
|
||||
now = datetime.datetime.now()
|
||||
return now > self.payment_expiry
|
||||
return now() > self.payment_expiry
|
||||
|
||||
A serializer definition that looked like this:
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
class AccountSerializer(serializers.HyperlinkedModelSerializer):
|
||||
expired = Field(source='has_expired')
|
||||
expired = serializers.Field(source='has_expired')
|
||||
|
||||
class Meta:
|
||||
fields = ('url', 'owner', 'name', 'expired')
|
||||
|
@ -125,12 +129,11 @@ The `ModelField` class is generally intended for internal use, but can be used b
|
|||
|
||||
This 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. The field's constructor accepts a single argument, which is the name of the method on the serializer to be called. The method should accept a single argument (in addition to `self`), which is the object being serialized. It should return whatever you want to be included in the serialized representation of the object. For example:
|
||||
|
||||
from rest_framework import serializers
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.timezone import now
|
||||
from rest_framework import serializers
|
||||
|
||||
class UserSerializer(serializers.ModelSerializer):
|
||||
|
||||
days_since_joined = serializers.SerializerMethodField('get_days_since_joined')
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -20,6 +20,10 @@ You can do so by filtering based on the value of `request.user`.
|
|||
|
||||
For example:
|
||||
|
||||
from myapp.models import Purchase
|
||||
from myapp.serializers import PurchaseSerializer
|
||||
from rest_framework import generics
|
||||
|
||||
class PurchaseList(generics.ListAPIView)
|
||||
serializer_class = PurchaseSerializer
|
||||
|
||||
|
@ -90,6 +94,11 @@ 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,
|
||||
using the `GenericAPIView` class based views.
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from myapp.serializers import UserSerializer
|
||||
from rest_framework import filters
|
||||
from rest_framework import generics
|
||||
|
||||
class UserListView(generics.ListAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer = UserSerializer
|
||||
|
@ -150,6 +159,11 @@ This will automatically create a `FilterSet` class for the given fields, and wil
|
|||
|
||||
For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view. For example:
|
||||
|
||||
import django_filters
|
||||
from myapp.models import Product
|
||||
from myapp.serializers import ProductSerializer
|
||||
from rest_framework import generics
|
||||
|
||||
class ProductFilter(django_filters.FilterSet):
|
||||
min_price = django_filters.NumberFilter(lookup_type='gte')
|
||||
max_price = django_filters.NumberFilter(lookup_type='lte')
|
||||
|
|
|
@ -17,6 +17,11 @@ If the generic views don't suit the needs of your API, you can drop down to usin
|
|||
|
||||
Typically when using the generic views, you'll override the view, and set several class attributes.
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from myapp.serializers import UserSerializer
|
||||
from rest_framework import generics
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
|
||||
class UserList(generics.ListCreateAPIView):
|
||||
queryset = User.objects.all()
|
||||
serializer_class = UserSerializer
|
||||
|
|
|
@ -13,6 +13,7 @@ REST framework includes a `PaginationSerializer` class that makes it easy to ret
|
|||
Let's start by taking a look at an example from the Django documentation.
|
||||
|
||||
from django.core.paginator import Paginator
|
||||
|
||||
objects = ['john', 'paul', 'george', 'ringo']
|
||||
paginator = Paginator(objects, 2)
|
||||
page = paginator.page(1)
|
||||
|
@ -22,6 +23,7 @@ Let's start by taking a look at an example from the Django documentation.
|
|||
At this point we've got a page object. If we wanted to return this page object as a JSON response, we'd need to provide the client with context such as next and previous links, so that it would be able to page through the remaining results.
|
||||
|
||||
from rest_framework.pagination import PaginationSerializer
|
||||
|
||||
serializer = PaginationSerializer(instance=page)
|
||||
serializer.data
|
||||
# {'count': 4, 'next': '?page=2', 'previous': None, 'results': [u'john', u'paul']}
|
||||
|
@ -114,6 +116,9 @@ You can also override the name used for the object list field, by setting the `r
|
|||
|
||||
For example, to nest a pair of links labelled 'prev' and 'next', and set the name for the results field to 'objects', you might use something like this.
|
||||
|
||||
from rest_framework import pagination
|
||||
from rest_framework import serializers
|
||||
|
||||
class LinksSerializer(serializers.Serializer):
|
||||
next = pagination.NextPageField(source='*')
|
||||
prev = pagination.PreviousPageField(source='*')
|
||||
|
@ -135,7 +140,7 @@ To have your custom pagination serializer be used by default, use the `DEFAULT_P
|
|||
|
||||
Alternatively, to set your custom pagination serializer on a per-view basis, use the `pagination_serializer_class` attribute on a generic class based view:
|
||||
|
||||
class PaginatedListView(ListAPIView):
|
||||
class PaginatedListView(generics.ListAPIView):
|
||||
model = ExampleModel
|
||||
pagination_serializer_class = CustomPaginationSerializer
|
||||
paginate_by = 10
|
||||
|
|
|
@ -37,6 +37,10 @@ The default set of parsers may be set globally, using the `DEFAULT_PARSER_CLASSE
|
|||
You can also set the renderers used for an individual view, or viewset,
|
||||
using the `APIView` class based views.
|
||||
|
||||
from rest_framework.parsers import YAMLParser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class ExampleView(APIView):
|
||||
"""
|
||||
A view that can accept POST requests with YAML content.
|
||||
|
|
|
@ -47,6 +47,10 @@ 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,
|
||||
using the `APIView` class based views.
|
||||
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.responses import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class ExampleView(APIView):
|
||||
permission_classes = (IsAuthenticated,)
|
||||
|
||||
|
@ -157,6 +161,8 @@ For more details see the [2.2 release announcement][2.2-announcement].
|
|||
|
||||
The 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.
|
||||
|
||||
from rest_framework import permissions
|
||||
|
||||
class BlacklistPermission(permissions.BasePermission):
|
||||
"""
|
||||
Global permission check for blacklisted IPs.
|
||||
|
|
|
@ -76,7 +76,7 @@ This field is read only.
|
|||
For example, the following serializer:
|
||||
|
||||
class AlbumSerializer(serializers.ModelSerializer):
|
||||
tracks = PrimaryKeyRelatedField(many=True, read_only=True)
|
||||
tracks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Album
|
||||
|
@ -110,8 +110,8 @@ By default this field is read-write, although you can change this behavior using
|
|||
For example, the following serializer:
|
||||
|
||||
class AlbumSerializer(serializers.ModelSerializer):
|
||||
tracks = HyperlinkedRelatedField(many=True, read_only=True,
|
||||
view_name='track-detail')
|
||||
tracks = serializers.HyperlinkedRelatedField(many=True, read_only=True,
|
||||
view_name='track-detail')
|
||||
|
||||
class Meta:
|
||||
model = Album
|
||||
|
@ -148,7 +148,8 @@ By default this field is read-write, although you can change this behavior using
|
|||
For example, the following serializer:
|
||||
|
||||
class AlbumSerializer(serializers.ModelSerializer):
|
||||
tracks = SlugRelatedField(many=True, read_only=True, slug_field='title')
|
||||
tracks = serializers.SlugRelatedField(many=True, read_only=True,
|
||||
slug_field='title')
|
||||
|
||||
class Meta:
|
||||
model = Album
|
||||
|
@ -183,7 +184,7 @@ When using `SlugRelatedField` as a read-write field, you will normally want to e
|
|||
This field can be applied as an identity relationship, such as the `'url'` field on a HyperlinkedModelSerializer. It can also be used for an attribute on the object. For example, the following serializer:
|
||||
|
||||
class AlbumSerializer(serializers.HyperlinkedModelSerializer):
|
||||
track_listing = HyperlinkedIdentityField(view_name='track-list')
|
||||
track_listing = serializers.HyperlinkedIdentityField(view_name='track-list')
|
||||
|
||||
class Meta:
|
||||
model = Album
|
||||
|
|
|
@ -30,11 +30,16 @@ 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,
|
||||
using the `APIView` class based views.
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework.renderers import JSONRenderer, YAMLRenderer
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class UserCountView(APIView):
|
||||
"""
|
||||
A view that returns the count of active users, in JSON or JSONp.
|
||||
A view that returns the count of active users, in JSON or YAML.
|
||||
"""
|
||||
renderer_classes = (JSONRenderer, JSONPRenderer)
|
||||
renderer_classes = (JSONRenderer, YAMLRenderer)
|
||||
|
||||
def get(self, request, format=None):
|
||||
user_count = User.objects.filter(active=True).count()
|
||||
|
|
|
@ -27,13 +27,13 @@ Has the same behavior as [`django.core.urlresolvers.reverse`][reverse], except t
|
|||
|
||||
You should **include the request as a keyword argument** to the function, for example:
|
||||
|
||||
import datetime
|
||||
from rest_framework.reverse import reverse
|
||||
from rest_framework.views import APIView
|
||||
from django.utils.timezone import now
|
||||
|
||||
class APIRootView(APIView):
|
||||
def get(self, request):
|
||||
year = datetime.datetime.now().year
|
||||
year = now().year
|
||||
data = {
|
||||
...
|
||||
'year-summary-url': reverse('year-summary', args=[year], request=request)
|
||||
|
|
|
@ -14,6 +14,8 @@ REST framework adds support for automatic URL routing to Django, and provides yo
|
|||
|
||||
Here's an example of a simple URL conf, that uses `DefaultRouter`.
|
||||
|
||||
from rest_framework import routers
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r'users', UserViewSet)
|
||||
router.register(r'accounts', AccountViewSet)
|
||||
|
@ -40,6 +42,9 @@ The example above would generate the following URL patterns:
|
|||
Any methods on the viewset decorated with `@link` or `@action` will also be routed.
|
||||
For example, given a method like this on the `UserViewSet` class:
|
||||
|
||||
from myapp.permissions import IsAdminOrIsSelf
|
||||
from rest_framework.decorators import action
|
||||
|
||||
@action(permission_classes=[IsAdminOrIsSelf])
|
||||
def set_password(self, request, pk=None):
|
||||
...
|
||||
|
@ -120,6 +125,8 @@ The arguments to the `Route` named tuple are:
|
|||
|
||||
The following example will only route to the `list` and `retrieve` actions, and does not use the trailing slash convention.
|
||||
|
||||
from rest_framework.routers import Route, SimpleRouter
|
||||
|
||||
class ReadOnlyRouter(SimpleRouter):
|
||||
"""
|
||||
A router for read-only APIs, which doesn't use trailing slashes.
|
||||
|
|
|
@ -28,6 +28,8 @@ We'll declare a serializer that we can use to serialize and deserialize `Comment
|
|||
|
||||
Declaring a serializer looks very similar to declaring a form:
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
class CommentSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField()
|
||||
content = serializers.CharField(max_length=200)
|
||||
|
@ -59,6 +61,8 @@ We can now use `CommentSerializer` to serialize a comment, or list of comments.
|
|||
|
||||
At this point we've translated the model instance into Python native datatypes. To finalise the serialization process we render the data into `json`.
|
||||
|
||||
from rest_framework.renderers import JSONRenderer
|
||||
|
||||
json = JSONRenderer().render(serializer.data)
|
||||
json
|
||||
# '{"email": "leila@example.com", "content": "foo bar", "created": "2012-08-22T16:20:09.822"}'
|
||||
|
@ -67,6 +71,9 @@ At this point we've translated the model instance into Python native datatypes.
|
|||
|
||||
Deserialization is similar. First we parse a stream into Python native datatypes...
|
||||
|
||||
from StringIO import StringIO
|
||||
from rest_framework.parsers import JSONParser
|
||||
|
||||
stream = StringIO(json)
|
||||
data = JSONParser().parse(stream)
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
Using bare status codes in your responses isn't recommended. REST framework includes a set of named constants that you can use to make more code more obvious and readable.
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
|
||||
def empty_view(self):
|
||||
content = {'please move along': 'nothing to see here'}
|
||||
|
|
|
@ -16,6 +16,8 @@ Extends [Django's existing `RequestFactory` class][requestfactory].
|
|||
|
||||
The `APIRequestFactory` class supports an almost identical API to Django's standard `RequestFactory` class. This means the that standard `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()` and `.options()` methods are all available.
|
||||
|
||||
from rest_framework.test import APIRequestFactory
|
||||
|
||||
# Using the standard RequestFactory API to create a form POST request
|
||||
factory = APIRequestFactory()
|
||||
request = factory.post('/notes/', {'title': 'new idea'})
|
||||
|
@ -49,6 +51,8 @@ For example, using `APIRequestFactory`, you can make a form PUT request like so:
|
|||
|
||||
Using Django's `RequestFactory`, you'd need to explicitly encode the data yourself:
|
||||
|
||||
from django.test.client import encode_multipart, RequestFactory
|
||||
|
||||
factory = RequestFactory()
|
||||
data = {'title': 'remember to email dave'}
|
||||
content = encode_multipart('BoUnDaRyStRiNg', data)
|
||||
|
@ -72,6 +76,12 @@ To forcibly authenticate a request, use the `force_authenticate()` method.
|
|||
|
||||
The signature for the method is `force_authenticate(request, user=None, token=None)`. When making the call, either or both of the user and token may be set.
|
||||
|
||||
For example, when forcibly authenticating using a token, you might do something like the following:
|
||||
|
||||
user = User.objects.get(username='olivia')
|
||||
request = factory.get('/accounts/django-superstars/')
|
||||
force_authenticate(request, user=user, token=user.token)
|
||||
|
||||
---
|
||||
|
||||
**Note**: When using `APIRequestFactory`, the object that is returned is Django's standard `HttpRequest`, and not REST framework's `Request` object, which is only generated once the view is called.
|
||||
|
@ -105,6 +115,8 @@ Extends [Django's existing `Client` class][client].
|
|||
|
||||
The `APIClient` class supports the same request interface as `APIRequestFactory`. This means the that standard `.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`, `.head()` and `.options()` methods are all available. For example:
|
||||
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
client = APIClient()
|
||||
client.post('/notes/', {'title': 'new idea'}, format='json')
|
||||
|
||||
|
@ -131,8 +143,11 @@ The `login` method is appropriate for testing APIs that use session authenticati
|
|||
|
||||
The `credentials` method can be used to set headers that will then be included on all subsequent requests by the test client.
|
||||
|
||||
from rest_framework.authtoken.models import Token
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
# Include an appropriate `Authorization:` header on all requests.
|
||||
token = Token.objects.get(username='lauren')
|
||||
token = Token.objects.get(user__username='lauren')
|
||||
client = APIClient()
|
||||
client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)
|
||||
|
||||
|
@ -190,10 +205,10 @@ You can use any of REST framework's test case classes as you would for the regul
|
|||
Ensure we can create a new account object.
|
||||
"""
|
||||
url = reverse('account-list')
|
||||
data = {'name': 'DabApps'}
|
||||
expected = {'name': 'DabApps'}
|
||||
response = self.client.post(url, data, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertEqual(response.data, data)
|
||||
self.assertEqual(response.data, expected)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -43,6 +43,10 @@ The rate descriptions used in `DEFAULT_THROTTLE_RATES` may include `second`, `mi
|
|||
You can also set the throttling policy on a per-view or per-viewset basis,
|
||||
using the `APIView` class based views.
|
||||
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.throttling import UserRateThrottle
|
||||
from rest_framework.views import APIView
|
||||
|
||||
class ExampleView(APIView):
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
|
|
|
@ -19,6 +19,12 @@ Typically, rather than explicitly registering the views in a viewset in the urlc
|
|||
|
||||
Let's define a simple viewset that can be used to list or retrieve all the users in the system.
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.shortcuts import get_object_or_404
|
||||
from myapps.serializers import UserSerializer
|
||||
from rest_framework import viewsets
|
||||
from rest_framewor.responses import Response
|
||||
|
||||
class UserViewSet(viewsets.ViewSet):
|
||||
"""
|
||||
A simple ViewSet that for listing or retrieving users.
|
||||
|
@ -41,6 +47,9 @@ If we need to, we can bind this viewset into two separate views, like so:
|
|||
|
||||
Typically we wouldn't do this, but would instead register the viewset with a router, and allow the urlconf to be automatically generated.
|
||||
|
||||
from myapp.views import UserViewSet
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register(r'users', UserViewSet)
|
||||
urlpatterns = router.urls
|
||||
|
|
Loading…
Reference in New Issue
Block a user