From e4fff6ea6e5422af23c324897ed1cff8f8a6e903 Mon Sep 17 00:00:00 2001 From: "tom christie tom@tomchristie.com" Date: Sat, 19 Feb 2011 13:12:35 +0000 Subject: [PATCH] Clean up the docs --- djangorestframework/authenticators.py | 11 +- djangorestframework/emitters.py | 7 + docs/examples/blogpost.rst | 6 +- docs/examples/modelresources.rst | 50 ++++++++ docs/examples/objectstore.rst | 6 +- docs/examples/pygments.rst | 10 +- docs/examples/resources.rst | 48 +++++++ docs/examples/sandbox.rst | 14 ++ docs/howto/mixin.rst | 30 +++++ docs/howto/setup.rst | 28 ++++ docs/howto/usingcurl.rst | 6 +- docs/index.rst | 177 +++++++++----------------- docs/library/authenticators.rst | 29 +---- docs/library/resource.rst | 2 +- docs/library/status.rst | 5 + docs/library/validators.rst | 5 + 16 files changed, 272 insertions(+), 162 deletions(-) create mode 100644 docs/examples/modelresources.rst create mode 100644 docs/examples/resources.rst create mode 100644 docs/examples/sandbox.rst create mode 100644 docs/howto/mixin.rst create mode 100644 docs/howto/setup.rst create mode 100644 docs/library/status.rst create mode 100644 docs/library/validators.rst diff --git a/djangorestframework/authenticators.py b/djangorestframework/authenticators.py index 85ba9f114..29875c643 100644 --- a/djangorestframework/authenticators.py +++ b/djangorestframework/authenticators.py @@ -1,3 +1,9 @@ +"""The :mod:`authenticators` modules provides for pluggable authentication behaviour. + +Authentication behaviour is provided by adding the mixin class :class:`AuthenticatorMixin` to a :class:`.Resource` or Django :class:`View` class. + +The set of authenticators which are use is then specified by setting the :attr:`authenticators` attribute on the class, and listing a set of authenticator classes. +""" from django.contrib.auth import authenticate from django.middleware.csrf import CsrfViewMiddleware from djangorestframework.utils import as_tuple @@ -5,11 +11,14 @@ import base64 class AuthenticatorMixin(object): + """Adds pluggable authentication behaviour.""" + + """The set of authenticators to use.""" authenticators = None def authenticate(self, request): """Attempt to authenticate the request, returning an authentication context or None. - An authentication context may be any object, although in many cases it will be a User instance.""" + An authentication context may be any object, although in many cases it will simply be a :class:`User` instance.""" # Attempt authentication against each authenticator in turn, # and return None if no authenticators succeed in authenticating the request. diff --git a/djangorestframework/emitters.py b/djangorestframework/emitters.py index 6e101e866..be1d7ef30 100644 --- a/djangorestframework/emitters.py +++ b/djangorestframework/emitters.py @@ -32,6 +32,12 @@ _MSIE_USER_AGENT = re.compile(r'^Mozilla/[0-9]+\.[0-9]+ \([^)]*; MSIE [0-9]+\.[0 class EmitterMixin(object): + """Adds behaviour for pluggable Emitters to a :class:`.Resource` or Django :class:`View`. class. + + Default behaviour is to use standard HTTP Accept header content negotiation. + Also supports overidding the content type by specifying an _accept= parameter in the URL. + Ignores Accept headers from Internet Explorer user agents and uses a sensible browser Accept header instead.""" + ACCEPT_QUERY_PARAM = '_accept' # Allow override of Accept header in URL query params REWRITE_IE_ACCEPT_HEADER = True @@ -40,6 +46,7 @@ class EmitterMixin(object): emitters = () def emit(self, response): + """Takes a :class:`Response` object and returns a Django :class:`HttpResponse`.""" self.response = response try: diff --git a/docs/examples/blogpost.rst b/docs/examples/blogpost.rst index aeb3d2fd8..07f7cbc56 100644 --- a/docs/examples/blogpost.rst +++ b/docs/examples/blogpost.rst @@ -1,5 +1,7 @@ -ModelResource example - Blog posts -================================== +.. _blogposts: + +Blog Posts API +============== * http://api.django-rest-framework.org/blog-post/ diff --git a/docs/examples/modelresources.rst b/docs/examples/modelresources.rst new file mode 100644 index 000000000..ec0fa36c9 --- /dev/null +++ b/docs/examples/modelresources.rst @@ -0,0 +1,50 @@ +.. _modelresources: + +Getting Started - Model Resources +--------------------------------- + +Often you'll want parts of your API to directly map to existing django models. Django REST framework handles this nicely for you in a couple of ways: + +#. It automatically provides suitable create/read/update/delete methods for your resources. +#. Input validation occurs automatically, by using appropriate `ModelForms `_. + +We'll start of defining two resources in our urlconf again. + +``urls.py`` + +.. include:: ../../examples/modelresourceexample/urls.py + :literal: + +Here's the models we're working from in this example. It's usually a good idea to make sure you provide the :func:`get_absolute_url()` `permalink `_ for all models you want to expose via the API. + +``models.py`` + +.. include:: ../../examples/modelresourceexample/models.py + :literal: + +Now that we've got some models and a urlconf, there's very little code to write. We'll create a :class:`.ModelResource` to map to instances of our models, and a top level :class:`.RootModelResource` to list the existing instances and to create new instances. + +``views.py`` + +.. include:: ../../examples/modelresourceexample/views.py + :literal: + +And we're done. We've now got a fully browseable API, which supports multiple input and output media types, and has all the nice automatic field validation that Django gives us for free. + +We can visit the API in our browser: + +* http://api.django-rest-framework.org/model-resource-example/ + +Or access it from the command line using curl: + +.. code-block:: bash + + # Demonstrates API's input validation using form input + bash: curl -X POST --data 'foo=true' http://api.django-rest-framework.org/model-resource-example/ + {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} + + # Demonstrates API's input validation using JSON input + bash: curl -X POST -H 'Content-Type: application/json' --data-binary '{"foo":true}' http://api.django-rest-framework.org/model-resource-example/ + {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} + +We could also have added the handler methods :meth:`.Resource.get()`, :meth:`.Resource.post()` etc... seen in the last example, but Django REST framework provides nice default implementations for us that do exactly what we'd expect them to. diff --git a/docs/examples/objectstore.rst b/docs/examples/objectstore.rst index 7865242d4..38bdbc983 100644 --- a/docs/examples/objectstore.rst +++ b/docs/examples/objectstore.rst @@ -1,5 +1,7 @@ -Resource example - An object store -================================== +.. _objectstore: + +Object Store API +================ * http://api.django-rest-framework.org/object-store/ diff --git a/docs/examples/pygments.rst b/docs/examples/pygments.rst index 6ba2805f3..decc2f657 100644 --- a/docs/examples/pygments.rst +++ b/docs/examples/pygments.rst @@ -1,5 +1,7 @@ -Resource with form validation - A pygments pastebin -=================================================== +.. _codehighlighting: + +Code Highlighting API +===================== This example demonstrates creating a REST API using a :class:`.Resource` with some form validation on the input. We're going to provide a simple wrapper around the awesome `pygments `_ library, to create the Web API for a simple pastebin. @@ -8,12 +10,10 @@ We're going to provide a simple wrapper around the awesome `pygments `_. - #. See `using CURL with django-rest-framework `_ for more details. URL configuration ----------------- diff --git a/docs/examples/resources.rst b/docs/examples/resources.rst new file mode 100644 index 000000000..0b76c466c --- /dev/null +++ b/docs/examples/resources.rst @@ -0,0 +1,48 @@ +.. _resources: + +Getting Started - Resources +--------------------------- + +We're going to start off with a simple example, that demonstrates a few things: + +#. Creating resources. +#. Linking resources. +#. Writing method handlers on resources. +#. Adding form validation to resources. + +First we'll define two resources in our urlconf. + +``urls.py`` + +.. include:: ../../examples/resourceexample/urls.py + :literal: + +Now we'll add a form that we'll use for input validation. This is completely optional, but it's often useful. + +``forms.py`` + +.. include:: ../../examples/resourceexample/forms.py + :literal: + +Now we'll write our resources. The first is a read only resource that links to three instances of the second. The second resource just has some stub handler methods to help us see that our example is working. + +``views.py`` + +.. include:: ../../examples/resourceexample/views.py + :literal: + +That's us done. Our API now provides both programmatic access using JSON and XML, as well a nice browseable HTML view, so we can now access it both from the browser: + +* http://api.django-rest-framework.org/resource-example/ + +And from the command line: + +.. code-block:: bash + + # Demonstrates API's input validation using form input + bash: curl -X POST --data 'foo=true' http://api.django-rest-framework.org/resource-example/1/ + {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} + + # Demonstrates API's input validation using JSON input + bash: curl -X POST -H 'Content-Type: application/json' --data-binary '{"foo":true}' http://api.django-rest-framework.org/resource-example/1/ + {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} diff --git a/docs/examples/sandbox.rst b/docs/examples/sandbox.rst new file mode 100644 index 000000000..b6658ad9c --- /dev/null +++ b/docs/examples/sandbox.rst @@ -0,0 +1,14 @@ +.. _sandbox: + +Sandbox Root API +================ + +The Resource +------------ + +The root level resource of the Django REST framework examples is a simple read only resource: + +``view.py`` + +.. include:: ../../examples/sandbox/views.py + :literal: diff --git a/docs/howto/mixin.rst b/docs/howto/mixin.rst new file mode 100644 index 000000000..68a736906 --- /dev/null +++ b/docs/howto/mixin.rst @@ -0,0 +1,30 @@ +Using Django REST framework Mixin classes +========================================= + +This example demonstrates creating a REST API **without** using Django REST framework's :class:`.Resource` or :class:`.ModelResource`, +but instead using Django :class:`View` class, and adding the :class:`EmitterMixin` class to provide full HTTP Accept header content negotiation, +a browseable Web API, and much of the other goodness that Django REST framework gives you for free. + +.. note:: + + A live sandbox instance of this API is available for testing: + + * http://api.django-rest-framework.org/mixin/ + + You can browse the API using a web browser, or from the command line:: + + curl -X GET http://api.django-rest-framework.org/mixin/ + + +URL configuration +----------------- + +Everything we need for this example can go straight into the URL conf... + +``urls.py`` + +.. include:: ../../examples/mixin/urls.py + :literal: + +That's it. Auto-magically our API now supports multiple output formats, specified either by using standard HTTP Accept header content negotiation, or by using the `&_accept=application/json` style parameter overrides. +We even get a nice HTML view which can be used to self-document our API. diff --git a/docs/howto/setup.rst b/docs/howto/setup.rst new file mode 100644 index 000000000..97b9e6d45 --- /dev/null +++ b/docs/howto/setup.rst @@ -0,0 +1,28 @@ +.. _setup: + +Setup +===== + +Template Loaders +---------------- + +Django REST framework uses a few templates for the HTML and plain text documenting emitters. + +* Ensure ``TEMPLATE_LOADERS`` setting contains ``'django.template.loaders.app_directories.Loader'``. + +This will be the case by default so you shouldn't normally need to do anything here. + +Admin Styling +------------- + +Django REST framework uses the admin media for styling. When running using Django's testserver this is automatically served for you, but once you move onto a production server, you'll want to make sure you serve the admin media seperatly, exactly as you would do if using the Django admin. + +* Ensure that the ``ADMIN_MEDIA_PREFIX`` is set appropriately and that you are serving the admin media. (Django's testserver will automatically serve the admin media for you) + +Markdown +-------- + +The Python `markdown library `_ is not required but comes recommended. + +If markdown is installed your :class:`.Resource` descriptions can include `markdown style formatting `_ which will be rendered by the HTML documenting emitter. + diff --git a/docs/howto/usingcurl.rst b/docs/howto/usingcurl.rst index a1f748c1e..e7edfef9f 100644 --- a/docs/howto/usingcurl.rst +++ b/docs/howto/usingcurl.rst @@ -17,11 +17,7 @@ There are a few things that can be helpful to remember when using CURL with djan curl -X GET -H 'Accept: text/plain' http://example.com/my-api/ -#. All POST requests should include an ```X-Requested-With: XMLHttpRequest`` header `_:: - - curl -X POST -H 'X-Requested-With: XMLHttpRequest' --data 'foo=bar' http://example.com/my-api/ - -#. ``POST`` and ``PUT`` requests can contain form data (ie ``Content-Type:: application/x-www-form-urlencoded``):: +#. ``POST`` and ``PUT`` requests can contain form data (ie ``Content-Type: application/x-www-form-urlencoded``):: curl -X PUT --data 'foo=bar' http://example.com/my-api/some-resource/ diff --git a/docs/index.rst b/docs/index.rst index 33eb3431e..d86b94681 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -9,29 +9,28 @@ Django REST framework Introduction ------------ -Django REST framework is a lightweight REST framework for Django. - -It aims to make it easy to build well-connected, self-describing Web APIs with a minimum of fuss. +Django REST framework aims to make it easy to build well-connected, self-describing Web APIs with a minimum of fuss. Features: -* Clean, simple, class-based views for Resources. -* Support for ModelResources with nice default implementations and input validation. -* Automatically provides a browse-able self-documenting API. -* Pluggable Emitters, Parsers and Authenticators - Easy to customise. -* Content type negotiation using Accept headers. +* Automatically provides a Django Admin style `browse-able self-documenting API `_. +* Clean, simple, views for Resources, using Django's new `class based views `_. +* Support for ModelResources with out-of-the-box default implementations and input validation. +* Pluggable :mod:`.emitters`, :mod:`parsers`, :mod:`validators` and :mod:`authenticators` - Easy to customise. +* Content type negotiation using HTTP Accept headers. * Optional support for forms as input validation. -* Modular architecture - Easy to extend and modify. +* Modular architecture - The MixIn classes can even be used without using the core :class:`.Resource` or :class:`.ModelResource` classes. + +For more information please head on over to the `discussion group `_. + +Bug reports and feature suggestions are greatful received on the `issue tracker `_. Requirements ------------ -* Python 2.6 -* Django 1.2 +* Python (2.5, 2.6, 2.7 supported) +* Django (1.2, 1.3 supported) -.. note:: - - Support for a wider range of Python & Django versions is planned, but right now django-rest-framework is only tested against these versions. Installation & Setup -------------------- @@ -43,148 +42,88 @@ To get a local copy of the repository use mercurial:: To add django-rest-framework to a django project: -* Copy or symlink the ``djangorestframework`` directory into python's ``site-packages`` directory, or otherwise ensure that the ``djangorestframework`` directory is on your ``PYTHONPATH``. +* Ensure that the ``djangorestframework`` directory is on your ``PYTHONPATH``. * Add ``djangorestframework`` to your ``INSTALLED_APPS``. -* Ensure the ``TEMPLATE_LOADERS`` setting contains the item ``'django.template.loaders.app_directories.Loader'``. (It will do by default, so you shouldn't normally need to do anything here.) -Getting Started - Resources ---------------------------- +That's normally all you'll need to do to get Django REST framework set up on a standard installation using the testserver. -We're going to start off with a simple example, that demonstrates -a few things: +For more information take a look at the :ref:`setup` section. -#. Creating resources. -#. Linking resources. -#. Writing method handlers on resources. -#. Adding form validation to resources. +Getting Started +--------------- -First we'll define two resources in our urlconf. +Using Django REST framework can be as simple as adding a few lines to your urlconf:: -``urls.py`` + from django.conf.urls.defaults import patterns, url + from djangorestframework import ModelResource, RootModelResource + from models import MyModel -.. include:: ../examples/resourceexample/urls.py - :literal: + urlpatterns = patterns('', + url(r'^$', RootModelResource.as_view(model=MyModel)), + url(r'^(?P[^/]+)/$', ModelResource.as_view(model=MyModel)), + ) -Now we'll add a form that we'll use for input validation. This is completely optional, but it's often useful. - -``forms.py`` - -.. include:: ../examples/resourceexample/forms.py - :literal: - -Now we'll write our resources. The first is a read only resource that links to three instances of the second. The second resource just has some stub handler methods to help us see that our example is working. - -``views.py`` - -.. include:: ../examples/resourceexample/views.py - :literal: - -That's us done. Our API now provides both programmatic access using JSON and XML, as well a nice browseable HTML view, so we can now access it both from the browser: - -* http://api.django-rest-framework.org/resource-example/ - -And from the command line: - -.. code-block:: bash - - # Demonstrates API's input validation using form input - bash: curl -X POST -H 'X-Requested-With: XMLHttpRequest' --data 'foo=true' http://api.django-rest-framework.org/resource-example/1/ - {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} - - # Demonstrates API's input validation using JSON input - bash: curl -X POST -H 'X-Requested-With: XMLHttpRequest' -H 'Content-Type: application/json' --data-binary '{"foo":true}' http://api.django-rest-framework.org/resource-example/1/ - {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} - -Getting Started - Model Resources ---------------------------------- - -Often you'll want parts of your API to directly map to existing django models. Django REST framework handles this nicely for you in a couple of ways: - -#. It automatically provides suitable create/read/update/delete methods for your resources. -#. Input validation occurs automatically, by using appropriate `ModelForms `_. - -We'll start of defining two resources in our urlconf again. - -``urls.py`` - -.. include:: ../examples/modelresourceexample/urls.py - :literal: - -Here's the models we're working from in this example. It's usually a good idea to make sure you provide the :func:`get_absolute_url()` `permalink `_ for all models you want to expose via the API. - -``models.py`` - -.. include:: ../examples/modelresourceexample/models.py - :literal: - -Now that we've got some models and a urlconf, there's very little code to write. We'll create a :class:`.ModelResource` to map to instances of our models, and a top level :class:`.RootModelResource` to list the existing instances and to create new instances. - -``views.py`` - -.. include:: ../examples/modelresourceexample/views.py - :literal: - -And we're done. We've now got a fully browseable API, which supports multiple input and output media types, and has all the nice automatic field validation that Django gives us for free. - -We can visit the API in our browser: - -* http://api.django-rest-framework.org/model-resource-example/ - -Or access it from the command line using curl: - -.. code-block:: bash - - # Demonstrates API's input validation using form input - bash: curl -X POST -H 'X-Requested-With: XMLHttpRequest' --data 'foo=true' http://api.django-rest-framework.org/model-resource-example/ - {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} - - # Demonstrates API's input validation using JSON input - bash: curl -X POST -H 'X-Requested-With: XMLHttpRequest' -H 'Content-Type: application/json' --data-binary '{"foo":true}' http://api.django-rest-framework.org/model-resource-example/ - {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}} - -We could also have added the handler methods :meth:`.Resource.get()`, :meth:`.Resource.post()` etc... seen in the last example, but Django REST framework provides nice default implementations for us that do exactly what we'd expect them to. +Django REST framework comes with two "getting started" examples. +#. :ref:`resources` +#. :ref:`modelresources` + Examples -------- -There's a few real world examples included with django-rest-framework. -These demonstrate the following use cases: +There are a few real world web API examples included with Django REST framework. -#. Using :class:`.Resource` for resources that do not map to models. -#. Using :class:`.Resource` with forms for input validation. -#. Using :class:`.ModelResource` for resources that map directly to models. +#. :ref:`objectstore` - Using :class:`.Resource` for resources that do not map to models. +#. :ref:`codehighlighting` - Using :class:`.Resource` with forms for input validation. +#. :ref:`blogposts` - Using :class:`.ModelResource` for resources that map directly to models. -All the examples are freely available for testing in the sandbox here: http://api.django-rest-framework.org +All the examples are freely available for testing in the sandbox: + +* http://api.django-rest-framework.org + +(The :ref:`sandbox` resource is also documented.) -.. toctree:: - :maxdepth: 1 - examples/objectstore - examples/pygments - examples/blogpost How Tos, FAQs & Notes --------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 1 + howto/setup howto/usingcurl howto/alternativeframeworks + howto/mixin Library Reference ----------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 1 library/resource library/modelresource library/emitters library/parsers library/authenticators + library/validators library/response + library/status +Examples Reference +------------------ + +.. toctree:: + :maxdepth: 1 + + examples/resources + examples/modelresources + examples/objectstore + examples/pygments + examples/blogpost + examples/sandbox + howto/mixin Indices and tables ------------------ diff --git a/docs/library/authenticators.rst b/docs/library/authenticators.rst index ec49c246e..407339f78 100644 --- a/docs/library/authenticators.rst +++ b/docs/library/authenticators.rst @@ -1,30 +1,5 @@ :mod:`authenticators` ===================== -.. module:: authenticators - -The authenticators module provides a standard set of authentication methods that can be plugged in to a :class:`.Resource`, as well as providing a template by which to write custom authentication methods. - -The base class --------------- - -All authenticators must subclass the :class:`BaseAuthenticator` class and override it's :func:`authenticate` method. - -.. class:: BaseAuthenticator - - .. method:: authenticate(request) - - Authenticate the request and return the authentication context or None. - - The default permission checking on :class:`.Resource` will use the allowed_methods attribute for permissions if the authentication context is not None, and use anon_allowed_methods otherwise. - - The authentication context is passed to the handler calls (eg :meth:`.Resource.get`, :meth:`.Resource.post` etc...) in order to allow them to apply any more fine grained permission checking at the point the response is being generated. - - This function must be overridden to be implemented. - -Provided authenticators ------------------------ - -.. note:: - - TODO - document this module properly +.. automodule:: authenticators + :members: diff --git a/docs/library/resource.rst b/docs/library/resource.rst index a34d63fbc..b6cf028e2 100644 --- a/docs/library/resource.rst +++ b/docs/library/resource.rst @@ -3,7 +3,7 @@ .. module:: resource -The :mod:`resource` module is the core of FlyWheel. It provides the :class:`Resource` base class which handles incoming HTTP requests and maps them to method calls, performing authentication, input deserialization, input validation and output serialization. +The :mod:`resource` module is the core of Django REST framework. It provides the :class:`Resource` base class which handles incoming HTTP requests and maps them to method calls, performing authentication, input deserialization, input validation and output serialization. Resources are created by sublassing :class:`Resource`, setting a number of class attributes, and overriding one or more methods. diff --git a/docs/library/status.rst b/docs/library/status.rst new file mode 100644 index 000000000..0c7596bc2 --- /dev/null +++ b/docs/library/status.rst @@ -0,0 +1,5 @@ +:mod:`status` +=============== + +.. automodule:: status + :members: diff --git a/docs/library/validators.rst b/docs/library/validators.rst new file mode 100644 index 000000000..acca71eb8 --- /dev/null +++ b/docs/library/validators.rst @@ -0,0 +1,5 @@ +:mod:`validators` +=============== + +.. automodule:: validators + :members: