mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-20 21:41:04 +03:00
Most of the actual work so far has been markup really.
This commit is contained in:
parent
49d4e50342
commit
92c015e049
|
@ -4,7 +4,7 @@ The :mod:`authentication` module provides a set of pluggable authentication clas
|
||||||
Authentication behavior is provided by mixing the :class:`mixins.AuthMixin` class into a :class:`View` class.
|
Authentication behavior is provided by mixing the :class:`mixins.AuthMixin` class into a :class:`View` class.
|
||||||
|
|
||||||
The set of authentication methods which are used is then specified by setting the
|
The set of authentication methods which are used is then specified by setting the
|
||||||
:attr:`authentication` attribute on the :class:`View` class, and listing a set of authentication classes.
|
:attr:`authentication` attribute on the :class:`View` class, and listing a set of :class:`authentication` classes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
|
@ -26,20 +26,19 @@ class BaseAuthenticaton(object):
|
||||||
|
|
||||||
def __init__(self, view):
|
def __init__(self, view):
|
||||||
"""
|
"""
|
||||||
:param view: :class:`Authentication` classes are always passed the current view on creation.
|
:class:`Authentication` classes are always passed the current view on creation.
|
||||||
"""
|
"""
|
||||||
self.view = view
|
self.view = view
|
||||||
|
|
||||||
def authenticate(self, request):
|
def authenticate(self, request):
|
||||||
"""
|
"""
|
||||||
:param request: Request to be authenticated
|
Authenticate the :obj:`request` and return a :obj:`User` instance or :const:`None`. [*]_
|
||||||
:rtype: :obj:`User` or None [*]_
|
|
||||||
|
|
||||||
.. [*] The authentication context *will* typically be a :obj:`User`,
|
.. [*] The authentication context *will* typically be a :obj:`User` object,
|
||||||
but it need not be. It can be any user-like object so long as the
|
but it need not be. It can be any user-like object so long as the
|
||||||
permissions classes on the view can handle the object and use
|
permissions classes (see the :mod:`permissions` module) on the view can handle the object and use
|
||||||
it to determine if the request has the required permissions or not.
|
it to determine if the request has the required permissions or not.
|
||||||
|
|
||||||
This can be an important distinction if you're implementing some token
|
This can be an important distinction if you're implementing some token
|
||||||
based authentication mechanism, where the authentication context
|
based authentication mechanism, where the authentication context
|
||||||
may be more involved than simply mapping to a :obj:`User`.
|
may be more involved than simply mapping to a :obj:`User`.
|
||||||
|
@ -55,7 +54,7 @@ class BasicAuthenticaton(BaseAuthenticaton):
|
||||||
def authenticate(self, request):
|
def authenticate(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a :obj:`User` if a correct username and password have been supplied
|
Returns a :obj:`User` if a correct username and password have been supplied
|
||||||
using HTTP Basic authentication. Otherwise returns `None`.
|
using HTTP Basic authentication. Otherwise returns :const:`None`.
|
||||||
"""
|
"""
|
||||||
from django.utils.encoding import smart_unicode, DjangoUnicodeDecodeError
|
from django.utils.encoding import smart_unicode, DjangoUnicodeDecodeError
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ class UserLoggedInAuthenticaton(BaseAuthenticaton):
|
||||||
|
|
||||||
def authenticate(self, request):
|
def authenticate(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a :obj:`User` if the request session currently has a logged in user, otherwise `None`.
|
Returns a :obj:`User` object if the request session currently has a logged in user. Otherwise returns :const:`None`.
|
||||||
"""
|
"""
|
||||||
# TODO: Switch this back to request.POST, and let FormParser/MultiPartParser deal with the consequences.
|
# TODO: Switch this back to request.POST, and let FormParser/MultiPartParser deal with the consequences.
|
||||||
if getattr(request, 'user', None) and request.user.is_active:
|
if getattr(request, 'user', None) and request.user.is_active:
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
"""Compatability module to provide support for backwards compatability with older versions of django/python"""
|
"""
|
||||||
|
Compatability module to provide support for backwards compatability with older versions of django/python
|
||||||
|
"""
|
||||||
|
|
||||||
# cStringIO only if it's available
|
# cStringIO only if it's available
|
||||||
try:
|
try:
|
||||||
|
@ -27,24 +29,25 @@ except ImportError:
|
||||||
# Lovely stuff
|
# Lovely stuff
|
||||||
class RequestFactory(Client):
|
class RequestFactory(Client):
|
||||||
"""
|
"""
|
||||||
Class that lets you create mock Request objects for use in testing.
|
Class that lets you create mock :obj:`Request` objects for use in testing.
|
||||||
|
|
||||||
Usage:
|
Usage::
|
||||||
|
|
||||||
rf = RequestFactory()
|
rf = RequestFactory()
|
||||||
get_request = rf.get('/hello/')
|
get_request = rf.get('/hello/')
|
||||||
post_request = rf.post('/submit/', {'foo': 'bar'})
|
post_request = rf.post('/submit/', {'foo': 'bar'})
|
||||||
|
|
||||||
This class re-uses the django.test.client.Client interface, docs here:
|
This class re-uses the :class:`django.test.client.Client` interface. Of which
|
||||||
http://www.djangoproject.com/documentation/testing/#the-test-client
|
you can find the docs here__.
|
||||||
|
|
||||||
Once you have a request object you can pass it to any view function,
|
__ http://www.djangoproject.com/documentation/testing/#the-test-client
|
||||||
just as if that view had been hooked up using a URLconf.
|
|
||||||
|
|
||||||
|
Once you have a :obj:`request` object you can pass it to any :func:`view` function,
|
||||||
|
just as if that :func:`view` had been hooked up using a URLconf.
|
||||||
"""
|
"""
|
||||||
def request(self, **request):
|
def request(self, **request):
|
||||||
"""
|
"""
|
||||||
Similar to parent class, but returns the request object as soon as it
|
Similar to parent class, but returns the :obj:`request` object as soon as it
|
||||||
has created it.
|
has created it.
|
||||||
"""
|
"""
|
||||||
environ = {
|
environ = {
|
||||||
|
@ -148,9 +151,11 @@ try:
|
||||||
import re
|
import re
|
||||||
|
|
||||||
class CustomSetextHeaderProcessor(markdown.blockprocessors.BlockProcessor):
|
class CustomSetextHeaderProcessor(markdown.blockprocessors.BlockProcessor):
|
||||||
"""Override markdown's SetextHeaderProcessor, so that ==== headers are <h2> and ---- headers are <h3>.
|
"""
|
||||||
|
Override `markdown`'s :class:`SetextHeaderProcessor`, so that ==== headers are <h2> and ---- headers are <h3>.
|
||||||
|
|
||||||
We use <h1> for the resource name."""
|
We use <h1> for the resource name.
|
||||||
|
"""
|
||||||
|
|
||||||
# Detect Setext-style header. Must be first 2 lines of block.
|
# Detect Setext-style header. Must be first 2 lines of block.
|
||||||
RE = re.compile(r'^.*?\n[=-]{3,}', re.MULTILINE)
|
RE = re.compile(r'^.*?\n[=-]{3,}', re.MULTILINE)
|
||||||
|
@ -172,8 +177,11 @@ try:
|
||||||
blocks.insert(0, '\n'.join(lines[2:]))
|
blocks.insert(0, '\n'.join(lines[2:]))
|
||||||
|
|
||||||
def apply_markdown(text):
|
def apply_markdown(text):
|
||||||
"""Simple wrapper around markdown.markdown to apply our CustomSetextHeaderProcessor,
|
"""
|
||||||
and also set the base level of '#' style headers to <h2>."""
|
Simple wrapper around :func:`markdown.markdown` to apply our :class:`CustomSetextHeaderProcessor`,
|
||||||
|
and also set the base level of '#' style headers to <h2>.
|
||||||
|
"""
|
||||||
|
|
||||||
extensions = ['headerid(level=2)']
|
extensions = ['headerid(level=2)']
|
||||||
safe_mode = False,
|
safe_mode = False,
|
||||||
output_format = markdown.DEFAULT_OUTPUT_FORMAT
|
output_format = markdown.DEFAULT_OUTPUT_FORMAT
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""
|
"""
|
||||||
The mixins module provides a set of reusable mixin classes that can be added to a ``View``.
|
The :mod:`mixins` module provides a set of reusable `mixin`
|
||||||
|
classes that can be added to a `View`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
|
@ -41,7 +42,7 @@ __all__ = (
|
||||||
|
|
||||||
class RequestMixin(object):
|
class RequestMixin(object):
|
||||||
"""
|
"""
|
||||||
Mixin class to provide request parsing behavior.
|
`Mixin` class to provide request parsing behavior.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_USE_FORM_OVERLOADING = True
|
_USE_FORM_OVERLOADING = True
|
||||||
|
@ -52,7 +53,7 @@ class RequestMixin(object):
|
||||||
"""
|
"""
|
||||||
The set of request parsers that the view can handle.
|
The set of request parsers that the view can handle.
|
||||||
|
|
||||||
Should be a tuple/list of classes as described in the ``parsers`` module.
|
Should be a tuple/list of classes as described in the :mod:`parsers` module.
|
||||||
"""
|
"""
|
||||||
parsers = ()
|
parsers = ()
|
||||||
|
|
||||||
|
@ -61,8 +62,8 @@ class RequestMixin(object):
|
||||||
"""
|
"""
|
||||||
Returns the HTTP method.
|
Returns the HTTP method.
|
||||||
|
|
||||||
This should be used instead of ``request.method``, as it allows the method
|
This should be used instead of just reading :const:`request.method`, as it allows the `method`
|
||||||
to be overridden by using a hidden form field on a form POST request.
|
to be overridden by using a hidden `form` field on a form POST request.
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_method'):
|
if not hasattr(self, '_method'):
|
||||||
self._load_method_and_content_type()
|
self._load_method_and_content_type()
|
||||||
|
@ -100,7 +101,7 @@ class RequestMixin(object):
|
||||||
def FILES(self):
|
def FILES(self):
|
||||||
"""
|
"""
|
||||||
Parses the request body and returns the files.
|
Parses the request body and returns the files.
|
||||||
Similar to request.FILES, except that it handles arbitrary parsers,
|
Similar to ``request.FILES``, except that it handles arbitrary parsers,
|
||||||
and also works on methods other than POST (eg PUT).
|
and also works on methods other than POST (eg PUT).
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_files'):
|
if not hasattr(self, '_files'):
|
||||||
|
@ -215,10 +216,10 @@ class RequestMixin(object):
|
||||||
|
|
||||||
class ResponseMixin(object):
|
class ResponseMixin(object):
|
||||||
"""
|
"""
|
||||||
Adds behavior for pluggable Renderers to a :class:`.BaseView` or Django :class:`View`. class.
|
Adds behavior for pluggable `Renderers` to a :class:`views.BaseView` or Django :class:`View` class.
|
||||||
|
|
||||||
Default behavior is to use standard HTTP Accept header content negotiation.
|
Default behavior is to use standard HTTP Accept header content negotiation.
|
||||||
Also supports overriding the content type by specifying an _accept= parameter in the URL.
|
Also supports overriding 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.
|
Ignores Accept headers from Internet Explorer user agents and uses a sensible browser Accept header instead.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -228,7 +229,7 @@ class ResponseMixin(object):
|
||||||
"""
|
"""
|
||||||
The set of response renderers that the view can handle.
|
The set of response renderers that the view can handle.
|
||||||
|
|
||||||
Should be a tuple/list of classes as described in the ``renderers`` module.
|
Should be a tuple/list of classes as described in the :mod:`renderers` module.
|
||||||
"""
|
"""
|
||||||
renderers = ()
|
renderers = ()
|
||||||
|
|
||||||
|
@ -237,7 +238,7 @@ class ResponseMixin(object):
|
||||||
# out of the box with existing Django classes that use render_to_response.
|
# out of the box with existing Django classes that use render_to_response.
|
||||||
def render(self, response):
|
def render(self, response):
|
||||||
"""
|
"""
|
||||||
Takes a ``Response`` object and returns an ``HttpResponse``.
|
Takes a :obj:`Response` object and returns an :obj:`HttpResponse`.
|
||||||
"""
|
"""
|
||||||
self.response = response
|
self.response = response
|
||||||
|
|
||||||
|
@ -354,21 +355,21 @@ class ResponseMixin(object):
|
||||||
|
|
||||||
class AuthMixin(object):
|
class AuthMixin(object):
|
||||||
"""
|
"""
|
||||||
Simple mixin class to add authentication and permission checking to a ``View`` class.
|
Simple :class:`mixin` class to add authentication and permission checking to a :class:`View` class.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The set of authentication types that this view can handle.
|
The set of authentication types that this view can handle.
|
||||||
|
|
||||||
|
|
||||||
Should be a tuple/list of classes as described in the ``authentication`` module.
|
Should be a tuple/list of classes as described in the :mod:`authentication` module.
|
||||||
"""
|
"""
|
||||||
authentication = ()
|
authentication = ()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The set of permissions that will be enforced on this view.
|
The set of permissions that will be enforced on this view.
|
||||||
|
|
||||||
Should be a tuple/list of classes as described in the ``permissions`` module.
|
Should be a tuple/list of classes as described in the :mod:`permissions` module.
|
||||||
"""
|
"""
|
||||||
permissions = ()
|
permissions = ()
|
||||||
|
|
||||||
|
@ -376,8 +377,8 @@ class AuthMixin(object):
|
||||||
@property
|
@property
|
||||||
def user(self):
|
def user(self):
|
||||||
"""
|
"""
|
||||||
Returns the user for the current request, as determined by the set of
|
Returns the :obj:`user` for the current request, as determined by the set of
|
||||||
authentication classes applied to the ``View``.
|
:class:`authentication` classes applied to the :class:`View`.
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_user'):
|
if not hasattr(self, '_user'):
|
||||||
self._user = self._authenticate()
|
self._user = self._authenticate()
|
||||||
|
@ -413,12 +414,10 @@ class AuthMixin(object):
|
||||||
class ResourceMixin(object):
|
class ResourceMixin(object):
|
||||||
"""
|
"""
|
||||||
Provides request validation and response filtering behavior.
|
Provides request validation and response filtering behavior.
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
Should be a class as described in the :mod:`resources` module.
|
||||||
Should be a class as described in the ``resources`` module.
|
|
||||||
|
|
||||||
The ``resource`` is an object that maps a view onto it's representation on the server.
|
The :obj:`resource` is an object that maps a view onto it's representation on the server.
|
||||||
|
|
||||||
It provides validation on the content of incoming requests,
|
It provides validation on the content of incoming requests,
|
||||||
and filters the object representation into a serializable object for the response.
|
and filters the object representation into a serializable object for the response.
|
||||||
|
@ -436,8 +435,8 @@ class ResourceMixin(object):
|
||||||
|
|
||||||
def validate_request(self, data, files):
|
def validate_request(self, data, files):
|
||||||
"""
|
"""
|
||||||
Given the request data return the cleaned, validated content.
|
Given the request *data* return the cleaned, validated content.
|
||||||
Typically raises a ErrorResponse with status code 400 (Bad Request) on failure.
|
Typically raises an :class:`response.ErrorResponse` with status code 400 (Bad Request) on failure.
|
||||||
"""
|
"""
|
||||||
resource = self.resource(self)
|
resource = self.resource(self)
|
||||||
return resource.validate_request(data, files)
|
return resource.validate_request(data, files)
|
||||||
|
@ -459,8 +458,8 @@ class ResourceMixin(object):
|
||||||
|
|
||||||
class InstanceMixin(object):
|
class InstanceMixin(object):
|
||||||
"""
|
"""
|
||||||
Mixin class that is used to identify a view class as being the canonical identifier
|
`Mixin` class that is used to identify a `View` class as being the canonical identifier
|
||||||
for the resources it is mapped too.
|
for the resources it is mapped to.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -482,7 +481,7 @@ class InstanceMixin(object):
|
||||||
|
|
||||||
class ReadModelMixin(object):
|
class ReadModelMixin(object):
|
||||||
"""
|
"""
|
||||||
Behavior to read a model instance on GET requests
|
Behavior to read a `model` instance on GET requests
|
||||||
"""
|
"""
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
model = self.resource.model
|
||||||
|
@ -501,7 +500,7 @@ class ReadModelMixin(object):
|
||||||
|
|
||||||
class CreateModelMixin(object):
|
class CreateModelMixin(object):
|
||||||
"""
|
"""
|
||||||
Behavior to create a model instance on POST requests
|
Behavior to create a `model` instance on POST requests
|
||||||
"""
|
"""
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
model = self.resource.model
|
||||||
|
@ -525,7 +524,7 @@ class CreateModelMixin(object):
|
||||||
|
|
||||||
class UpdateModelMixin(object):
|
class UpdateModelMixin(object):
|
||||||
"""
|
"""
|
||||||
Behavior to update a model instance on PUT requests
|
Behavior to update a `model` instance on PUT requests
|
||||||
"""
|
"""
|
||||||
def put(self, request, *args, **kwargs):
|
def put(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
model = self.resource.model
|
||||||
|
@ -550,7 +549,7 @@ class UpdateModelMixin(object):
|
||||||
|
|
||||||
class DeleteModelMixin(object):
|
class DeleteModelMixin(object):
|
||||||
"""
|
"""
|
||||||
Behavior to delete a model instance on DELETE requests
|
Behavior to delete a `model` instance on DELETE requests
|
||||||
"""
|
"""
|
||||||
def delete(self, request, *args, **kwargs):
|
def delete(self, request, *args, **kwargs):
|
||||||
model = self.resource.model
|
model = self.resource.model
|
||||||
|
@ -570,7 +569,7 @@ class DeleteModelMixin(object):
|
||||||
|
|
||||||
class ListModelMixin(object):
|
class ListModelMixin(object):
|
||||||
"""
|
"""
|
||||||
Behavior to list a set of model instances on GET requests
|
Behavior to list a set of `model` instances on GET requests
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# NB. Not obvious to me if it would be better to set this on the resource?
|
# NB. Not obvious to me if it would be better to set this on the resource?
|
||||||
|
|
|
@ -5,8 +5,9 @@ to general HTTP requests.
|
||||||
|
|
||||||
We need a method to be able to:
|
We need a method to be able to:
|
||||||
|
|
||||||
1) Determine the parsed content on a request for methods other than POST (eg typically also PUT)
|
1.) Determine the parsed content on a request for methods other than POST (eg typically also PUT)
|
||||||
2) Determine the parsed content on a request for media types other than application/x-www-form-urlencoded
|
|
||||||
|
2.) Determine the parsed content on a request for media types other than application/x-www-form-urlencoded
|
||||||
and multipart/form-data. (eg also handle multipart/json)
|
and multipart/form-data. (eg also handle multipart/json)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -22,47 +23,51 @@ __all__ = (
|
||||||
'BaseParser',
|
'BaseParser',
|
||||||
'JSONParser',
|
'JSONParser',
|
||||||
'PlainTextParser',
|
'PlainTextParser',
|
||||||
|
'DataFlatener',
|
||||||
'FormParser',
|
'FormParser',
|
||||||
'MultiPartParser'
|
'MultiPartParser',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseParser(object):
|
class BaseParser(object):
|
||||||
"""
|
"""
|
||||||
All parsers should extend BaseParser, specifying a media_type attribute,
|
All parsers should extend :class:`BaseParser`, specifying a :attr:`media_type` attribute,
|
||||||
and overriding the parse() method.
|
and overriding the :meth:`parse` method.
|
||||||
"""
|
"""
|
||||||
media_type = None
|
media_type = None
|
||||||
|
|
||||||
def __init__(self, view):
|
def __init__(self, view):
|
||||||
"""
|
"""
|
||||||
Initialize the parser with the ``View`` instance as state,
|
Initialize the parser with the ``View`` instance as state,
|
||||||
in case the parser needs to access any metadata on the ``View`` object.
|
in case the parser needs to access any metadata on the :obj:`View` object.
|
||||||
"""
|
"""
|
||||||
self.view = view
|
self.view = view
|
||||||
|
|
||||||
def can_handle_request(self, content_type):
|
def can_handle_request(self, content_type):
|
||||||
"""
|
"""
|
||||||
Returns `True` if this parser is able to deal with the given media type.
|
Returns :const:`True` if this parser is able to deal with the given *content_type*.
|
||||||
|
|
||||||
The default implementation for this function is to check the ``media_type``
|
The default implementation for this function is to check the *content_type*
|
||||||
argument against the ``media_type`` attribute set on the class to see if
|
argument against the :attr:`media_type` attribute set on the class to see if
|
||||||
they match.
|
they match.
|
||||||
|
|
||||||
This may be overridden to provide for other behavior, but typically you'll
|
This may be overridden to provide for other behavior, but typically you'll
|
||||||
instead want to just set the ``media_type`` attribute on the class.
|
instead want to just set the :attr:`media_type` attribute on the class.
|
||||||
"""
|
"""
|
||||||
return media_type_matches(content_type, self.media_type)
|
return media_type_matches(content_type, self.media_type)
|
||||||
|
|
||||||
def parse(self, stream):
|
def parse(self, stream):
|
||||||
"""
|
"""
|
||||||
Given a stream to read from, return the deserialized output.
|
Given a *stream* to read from, return the deserialized output.
|
||||||
Should return a 2-tuple of (data, files).
|
Should return a 2-tuple of (data, files).
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError("BaseParser.parse() Must be overridden to be implemented.")
|
raise NotImplementedError("BaseParser.parse() Must be overridden to be implemented.")
|
||||||
|
|
||||||
|
|
||||||
class JSONParser(BaseParser):
|
class JSONParser(BaseParser):
|
||||||
|
"""
|
||||||
|
Parses JSON-serialized data.
|
||||||
|
"""
|
||||||
media_type = 'application/json'
|
media_type = 'application/json'
|
||||||
|
|
||||||
def parse(self, stream):
|
def parse(self, stream):
|
||||||
|
@ -74,11 +79,14 @@ class JSONParser(BaseParser):
|
||||||
|
|
||||||
|
|
||||||
class DataFlatener(object):
|
class DataFlatener(object):
|
||||||
"""Utility object for flattening dictionaries of lists. Useful for "urlencoded" decoded data."""
|
"""
|
||||||
|
Utility object for flattening dictionaries of lists. Useful for "urlencoded" decoded data.
|
||||||
|
"""
|
||||||
|
# TODO: move me to utils ??
|
||||||
|
|
||||||
def flatten_data(self, data):
|
def flatten_data(self, data):
|
||||||
"""Given a data dictionary {<key>: <value_list>}, returns a flattened dictionary
|
"""Given a *data* dictionary ``{<key>: <value_list>}``, returns a flattened dictionary
|
||||||
with information provided by the method "is_a_list"."""
|
with information provided by the method :meth:`is_a_list`."""
|
||||||
flatdata = dict()
|
flatdata = dict()
|
||||||
for key, val_list in data.items():
|
for key, val_list in data.items():
|
||||||
if self.is_a_list(key, val_list):
|
if self.is_a_list(key, val_list):
|
||||||
|
@ -93,15 +101,13 @@ class DataFlatener(object):
|
||||||
return flatdata
|
return flatdata
|
||||||
|
|
||||||
def is_a_list(self, key, val_list):
|
def is_a_list(self, key, val_list):
|
||||||
"""Returns True if the parameter with name *key* is expected to be a list, or False otherwise.
|
"""Returns :const:`True` if the parameter with name *key* is expected to be a list, or :const:`False` otherwise.
|
||||||
*val_list* which is the received value for parameter *key* can be used to guess the answer."""
|
*val_list* which is the received value for parameter *key* can be used to guess the answer."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class PlainTextParser(BaseParser):
|
class PlainTextParser(BaseParser):
|
||||||
"""
|
"""
|
||||||
Plain text parser.
|
|
||||||
|
|
||||||
Simply returns the content of the stream.
|
Simply returns the content of the stream.
|
||||||
"""
|
"""
|
||||||
media_type = 'text/plain'
|
media_type = 'text/plain'
|
||||||
|
@ -113,10 +119,10 @@ class PlainTextParser(BaseParser):
|
||||||
class FormParser(BaseParser, DataFlatener):
|
class FormParser(BaseParser, DataFlatener):
|
||||||
"""
|
"""
|
||||||
The default parser for form data.
|
The default parser for form data.
|
||||||
Return a dict containing a single value for each non-reserved parameter.
|
Returns a dict containing a single value for each non-reserved parameter.
|
||||||
|
|
||||||
In order to handle select multiple (and having possibly more than a single value for each parameter),
|
In order to handle select multiple (and having possibly more than a single value for each parameter),
|
||||||
you can customize the output by subclassing the method 'is_a_list'."""
|
you can customize the output by subclassing the method :meth:`DataFlatener.is_a_list`."""
|
||||||
|
|
||||||
media_type = 'application/x-www-form-urlencoded'
|
media_type = 'application/x-www-form-urlencoded'
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class BasePermission(object):
|
||||||
|
|
||||||
def check_permission(self, auth):
|
def check_permission(self, auth):
|
||||||
"""
|
"""
|
||||||
Should simply return, or raise an ErrorResponse.
|
Should simply return, or raise an :class:`response.ErrorResponse`.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class IsAuthenticated(BasePermission):
|
||||||
if not user.is_authenticated():
|
if not user.is_authenticated():
|
||||||
raise _403_FORBIDDEN_RESPONSE
|
raise _403_FORBIDDEN_RESPONSE
|
||||||
|
|
||||||
class IsAdminUser():
|
class IsAdminUser(BasePermission):
|
||||||
"""
|
"""
|
||||||
Allows access only to admin users.
|
Allows access only to admin users.
|
||||||
"""
|
"""
|
||||||
|
@ -85,7 +85,7 @@ class PerUserThrottling(BasePermission):
|
||||||
"""
|
"""
|
||||||
Rate throttling of requests on a per-user basis.
|
Rate throttling of requests on a per-user basis.
|
||||||
|
|
||||||
The rate is set by a 'throttle' attribute on the ``View`` class.
|
The rate (requests / seconds) is set by a :attr:`throttle` attribute on the ``View`` class.
|
||||||
The attribute is a two tuple of the form (number of requests, duration in seconds).
|
The attribute is a two tuple of the form (number of requests, duration in seconds).
|
||||||
|
|
||||||
The user id will be used as a unique identifier if the user is authenticated.
|
The user id will be used as a unique identifier if the user is authenticated.
|
||||||
|
|
|
@ -36,8 +36,8 @@ __all__ = (
|
||||||
|
|
||||||
class BaseRenderer(object):
|
class BaseRenderer(object):
|
||||||
"""
|
"""
|
||||||
All renderers must extend this class, set the media_type attribute,
|
All renderers must extend this class, set the :attr:`media_type` attribute,
|
||||||
and override the render() function.
|
and override the :meth:`render` method.
|
||||||
"""
|
"""
|
||||||
media_type = None
|
media_type = None
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class BaseRenderer(object):
|
||||||
The requested media type is also passed to this method,
|
The requested media type is also passed to this method,
|
||||||
as it may contain parameters relevant to how the parser
|
as it may contain parameters relevant to how the parser
|
||||||
should render the output.
|
should render the output.
|
||||||
EG: 'application/json; indent=4'
|
EG: ``application/json; indent=4``
|
||||||
|
|
||||||
By default render simply returns the output as-is.
|
By default render simply returns the output as-is.
|
||||||
Override this method to provide for other behavior.
|
Override this method to provide for other behavior.
|
||||||
|
@ -102,8 +102,8 @@ class TemplateRenderer(BaseRenderer):
|
||||||
A Base class provided for convenience.
|
A Base class provided for convenience.
|
||||||
|
|
||||||
Render the object simply by using the given template.
|
Render the object simply by using the given template.
|
||||||
To create a template renderer, subclass this, and set
|
To create a template renderer, subclass this class, and set
|
||||||
the ``media_type`` and ``template`` attributes
|
the :attr:`media_type` and `:attr:template` attributes.
|
||||||
"""
|
"""
|
||||||
media_type = None
|
media_type = None
|
||||||
template = None
|
template = None
|
||||||
|
|
Loading…
Reference in New Issue
Block a user