From 95abe6e8445f59f9e52609b0c54d9276830dbfd3 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 25 Apr 2013 12:47:34 +0100 Subject: [PATCH] Cleanup docstrings --- docs/api-guide/viewsets.md | 4 +++ rest_framework/authentication.py | 2 +- rest_framework/decorators.py | 8 +++++ rest_framework/fields.py | 5 +++ rest_framework/filters.py | 4 +++ rest_framework/generics.py | 2 -- rest_framework/negotiation.py | 4 +++ rest_framework/pagination.py | 6 ++-- rest_framework/relations.py | 6 ++++ rest_framework/request.py | 5 ++- rest_framework/response.py | 6 ++++ rest_framework/serializers.py | 12 +++++++ rest_framework/throttling.py | 8 +++-- rest_framework/views.py | 2 +- rest_framework/viewsets.py | 54 ++++++++++++++++++++++---------- 15 files changed, 100 insertions(+), 28 deletions(-) diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 5aa66196e..2f0f112be 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -41,6 +41,10 @@ If we need to, we can bind this viewset into two seperate 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. + router = DefaultRouter() + router.register(r'users', UserViewSet, 'user') + urlpatterns = router.urls + There are two main advantages of using a `ViewSet` class over using a `View` class. * Repeated logic can be combined into a single class. In the above example, we only need to specify the `queryset` once, and it'll be used across multiple views. diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 1eebb5b9c..9caca7889 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -1,5 +1,5 @@ """ -Provides a set of pluggable authentication policies. +Provides various authentication policies. """ from __future__ import unicode_literals import base64 diff --git a/rest_framework/decorators.py b/rest_framework/decorators.py index 00b37f8b4..81e585e1c 100644 --- a/rest_framework/decorators.py +++ b/rest_framework/decorators.py @@ -1,3 +1,11 @@ +""" +The most imporant decorator in this module is `@api_view`, which is used +for writing function-based views with REST framework. + +There are also various decorators for setting the API policies on function +based views, as well as the `@action` and `@link` decorators, which are +used to annotate methods on viewsets that should be included by routers. +""" from __future__ import unicode_literals from rest_framework.compat import six from rest_framework.views import APIView diff --git a/rest_framework/fields.py b/rest_framework/fields.py index f3496b53e..949f68d64 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1,3 +1,8 @@ +""" +Serializer fields perform validation on incoming data. + +They are very similar to Django's form fields. +""" from __future__ import unicode_literals import copy diff --git a/rest_framework/filters.py b/rest_framework/filters.py index 413fa0d29..5e1cdbac2 100644 --- a/rest_framework/filters.py +++ b/rest_framework/filters.py @@ -1,3 +1,7 @@ +""" +Provides generic filtering backends that can be used to filter the results +returned by list views. +""" from __future__ import unicode_literals from rest_framework.compat import django_filters diff --git a/rest_framework/generics.py b/rest_framework/generics.py index 3440c01dd..56471cfa7 100644 --- a/rest_framework/generics.py +++ b/rest_framework/generics.py @@ -10,8 +10,6 @@ from django.http import Http404 from django.shortcuts import get_object_or_404 from django.utils.translation import ugettext as _ -### Base classes for the generic views ### - class GenericAPIView(views.APIView): """ diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index 0694d35f5..4d205c0e8 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -1,3 +1,7 @@ +""" +Content negotiation deals with selecting an appropriate renderer given the +incoming request. Typically this will be based on the request's Accept header. +""" from __future__ import unicode_literals from django.http import Http404 from rest_framework import exceptions diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index 03a7a30f8..d51ea929b 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -1,9 +1,11 @@ +""" +Pagination serializers determine the structure of the output that should +be used for paginated responses. +""" from __future__ import unicode_literals from rest_framework import serializers from rest_framework.templatetags.rest_framework import replace_query_param -# TODO: Support URLconf kwarg-style paging - class NextPageField(serializers.Field): """ diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 2a10e9af5..6bda7418e 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -1,3 +1,9 @@ +""" +Serializer fields that deal with relationships. + +These fields allow you to specify the style that should be used to represent +model relationships, including hyperlinks, primary keys, or slugs. +""" from __future__ import unicode_literals from django.core.exceptions import ObjectDoesNotExist, ValidationError from django.core.urlresolvers import resolve, get_script_prefix, NoReverseMatch diff --git a/rest_framework/request.py b/rest_framework/request.py index ffbbab338..a434659c1 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -1,11 +1,10 @@ """ -The :mod:`request` module provides a :class:`Request` class used to wrap the standard `request` -object received in all the views. +The Request class is used as a wrapper around the standard request object. The wrapped request then offers a richer API, in particular : - content automatically parsed according to `Content-Type` header, - and available as :meth:`.DATA` + and available as `request.DATA` - full support of PUT method, including support for file uploads - form overloading of HTTP method, content type and content """ diff --git a/rest_framework/response.py b/rest_framework/response.py index 5e1bf46e2..26e4ab371 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -1,3 +1,9 @@ +""" +The Response class in REST framework is similiar to HTTPResponse, except that +it is initialized with unrendered data, instead of a pre-rendered string. + +The appropriate renderer is called during Django's template response rendering. +""" from __future__ import unicode_literals from django.core.handlers.wsgi import STATUS_CODE_TEXT from django.template.response import SimpleTemplateResponse diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index b4327af1e..fb438b129 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -1,3 +1,15 @@ +""" +Serializers and ModelSerializers are similar to Forms and ModelForms. +Unlike forms, they are not constrained to dealing with HTML output, and +form encoded input. + +Serialization in REST framework is a two-phase process: + +1. Serializers marshal between complex types like model instances, and +python primatives. +2. The process of marshalling between python primatives and request and +response content is handled by parsers and renderers. +""" from __future__ import unicode_literals import copy import datetime diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index 810cad637..93ea9816c 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -1,3 +1,6 @@ +""" +Provides various throttling policies. +""" from __future__ import unicode_literals from django.core.cache import cache from rest_framework import exceptions @@ -28,9 +31,8 @@ class SimpleRateThrottle(BaseThrottle): A simple cache implementation, that only requires `.get_cache_key()` to be overridden. - The rate (requests / seconds) is set by a :attr:`throttle` attribute - on the :class:`.View` class. The attribute is a string of the form 'number of - requests/period'. + The rate (requests / seconds) is set by a `throttle` attribute on the View + class. The attribute is a string of the form 'number_of_requests/period'. Period should be one of: ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day') diff --git a/rest_framework/views.py b/rest_framework/views.py index b8e948e09..555fa2f40 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -1,5 +1,5 @@ """ -Provides an APIView class that is used as the base of all class-based views. +Provides an APIView class that is the base of all views in REST framework. """ from __future__ import unicode_literals from django.core.exceptions import PermissionDenied diff --git a/rest_framework/viewsets.py b/rest_framework/viewsets.py index 28ab30e2f..9133fd442 100644 --- a/rest_framework/viewsets.py +++ b/rest_framework/viewsets.py @@ -1,3 +1,21 @@ +""" +ViewSets are essentially just a type of class based view, that doesn't provide +any method handlers, such as `get()`, `post()`, etc... but instead has actions, +such as `list()`, `retrieve()`, `create()`, etc... + +Actions are only bound to methods at the point of instantiating the views. + + user_list = UserViewSet.as_view({'get': 'list'}) + user_detail = UserViewSet.as_view({'get': 'retrieve'}) + +Typically, rather than instantiate views from viewsets directly, you'll +regsiter the viewset with a router and let the URL conf be determined +automatically. + + router = DefaultRouter() + router.register(r'users', UserViewSet, 'user') + urlpatterns = router.urls +""" from functools import update_wrapper from django.utils.decorators import classonlymethod from rest_framework import views, generics, mixins @@ -15,13 +33,10 @@ class ViewSetMixin(object): view = MyViewSet.as_view({'get': 'list', 'post': 'create'}) """ - _is_viewset = True @classonlymethod def as_view(cls, actions=None, name_suffix=None, **initkwargs): """ - Main entry point for a request-response process. - Because of the way class based views create a closure around the instantiated view, we need to totally reimplement `.as_view`, and slightly modify the view function that is created and returned. @@ -64,19 +79,9 @@ class ViewSetMixin(object): class ViewSet(ViewSetMixin, views.APIView): - pass - - -# Note the inheritence of both MultipleObjectAPIView *and* SingleObjectAPIView -# is a bit weird given the diamond inheritence, but it will work for now. -# There's some implementation clean up that can happen later. -class ModelViewSet(mixins.CreateModelMixin, - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - mixins.ListModelMixin, - ViewSetMixin, - generics.GenericAPIView): + """ + The base ViewSet class does not provide any actions by default. + """ pass @@ -84,4 +89,21 @@ class ReadOnlyModelViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, ViewSetMixin, generics.GenericAPIView): + """ + A viewset that provides default `list()` and `retrieve()` actions. + """ + pass + + +class ModelViewSet(mixins.CreateModelMixin, + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + mixins.ListModelMixin, + ViewSetMixin, + generics.GenericAPIView): + """ + A viewset that provides default `create()`, `retrieve()`, `update()`, + `partial_update()`, `destroy()` and `list()` actions. + """ pass