diff --git a/api-guide/authentication.html b/api-guide/authentication.html index 95b4bde34..b87770129 100644 --- a/api-guide/authentication.html +++ b/api-guide/authentication.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -104,6 +107,10 @@

    authentication.py

    Authentication

    +
    +

    Auth needs to be pluggable.

    +

    — Jacob Kaplan-Moss, "REST worst practices"

    +

    Authentication is the mechanism of associating an incoming request with a set of identifying credentials, such as the user the request came from, or the token that it was signed with. The permission and throttling policies can then use those credentials to determine if the request should be permitted.

    REST framework provides a number of authentication policies out of the box, and also allows you to implement custom policies.

    Authentication will run the first time either the request.user or request.auth properties are accessed, and determines how those properties are initialized.

    @@ -147,17 +154,18 @@ def example_view(request, format=None):

    UserBasicAuthentication

    This policy uses HTTP Basic Authentication, signed against a user's username and password. User basic authentication is generally only appropriate for testing.

    -

    Note: If you run UserBasicAuthentication in production your API must be https only, or it will be completely insecure. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.

    +

    Note: If you run UserBasicAuthentication in production your API should be https only. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.

    If successfully authenticated, UserBasicAuthentication provides the following credentials.

    TokenAuthentication

    -

    This policy uses HTTP Authentication with no authentication scheme. Token basic authentication is appropriate for client-server setups, such as native desktop and mobile clients. The token key should be passed in as a string to the "Authorization" HTTP header. For example:

    +

    This policy uses simple token-based HTTP Authentication. Token basic authentication is appropriate for client-server setups, such as native desktop and mobile clients.

    +

    The token key should be passed in as a string to the "Authorization" HTTP header. For example:

    curl http://my.api.org/ -X POST -H "Authorization: 0123456789abcdef0123456789abcdef"
     
    -

    Note: If you run TokenAuthentication in production your API must be https only, or it will be completely insecure.

    +

    Note: If you run TokenAuthentication in production your API should be https only.

    If successfully authenticated, TokenAuthentication provides the following credentials.

    Custom authentication policies

    -

    To implement a custom authentication policy, subclass BaseAuthentication and override the authenticate(self, request) method. The method should return a two-tuple of (user, auth) if authentication succeeds, or None otherwise.

    +

    To implement a custom authentication policy, subclass BaseAuthentication and override the .authenticate(self, request) method. The method should return a two-tuple of (user, auth) if authentication succeeds, or None otherwise.

    @@ -197,5 +205,9 @@ def example_view(request, format=None): var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/content-negotiation.html b/api-guide/content-negotiation.html new file mode 100644 index 000000000..5048bd1db --- /dev/null +++ b/api-guide/content-negotiation.html @@ -0,0 +1,128 @@ + + + + Django REST framework + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    +

    Content negotiation

    +
    +

    HTTP has provisions for several mechanisms for "content negotiation" - the process of selecting the best representation for a given response when there are multiple representations available.

    +

    RFC 2616, Fielding et al.

    +
    +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/api-guide/contentnegotiation.html b/api-guide/contentnegotiation.html index 2e6523f1e..25e179f42 100644 --- a/api-guide/contentnegotiation.html +++ b/api-guide/contentnegotiation.html @@ -7,10 +7,10 @@ - - - - + + + + - - - - - + + + + + \ No newline at end of file diff --git a/api-guide/exceptions.html b/api-guide/exceptions.html index ab0d8de6b..907abaf7a 100644 --- a/api-guide/exceptions.html +++ b/api-guide/exceptions.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -89,6 +92,13 @@
    @@ -97,6 +107,55 @@

    exceptions.py

    Exceptions

    +
    +

    Exceptions… allow error handling to be organized cleanly in a central or high-level place within the program structure.

    +

    — Doug Hellmann, Python Exception Handling Techniques

    +
    +

    Exception handling in REST framework views

    +

    REST framework's views handle various exceptions, and deal with returning appropriate error responses for you.

    +

    The handled exceptions are:

    + +

    In each case, REST framework will return a response, rendering it to an appropriate content-type.

    +

    By default all error messages will include a key details in the body of the response, but other keys may also be included.

    +

    For example, the following request:

    +
    DELETE http://api.example.com/foo/bar HTTP/1.1
    +Accept: application/json
    +
    +

    Might recieve an error response indicating that the DELETE method is not allowed on that resource:

    +
    HTTP/1.1 405 Method Not Allowed
    +Content-Type: application/json; charset=utf-8
    +Content-Length: 42
    +
    +{"detail": "Method 'DELETE' not allowed."}
    +
    +

    APIException

    +

    Signature: APIException(detail=None)

    +

    The base class for all exceptions raised inside REST framework.

    +

    To provide a custom exception, subclass APIException and set the .status_code and .detail properties on the class.

    +

    ParseError

    +

    Signature: ParseError(detail=None)

    +

    Raised if the request contains malformed data when accessing request.DATA or request.FILES.

    +

    By default this exception results in a response with the HTTP status code "400 Bad Request".

    +

    PermissionDenied

    +

    Signature: PermissionDenied(detail=None)

    +

    Raised when an incoming request fails the permission checks.

    +

    By default this exception results in a response with the HTTP status code "403 Forbidden".

    +

    MethodNotAllowed

    +

    Signature: MethodNotAllowed(method, detail=None)

    +

    Raised when an incoming request occurs that does not map to a handler method on the view.

    +

    By default this exception results in a response with the HTTP status code "405 Method Not Allowed".

    +

    UnsupportedMediaType

    +

    Signature: UnsupportedMediaType(media_type, detail=None)

    +

    Raised if there are no parsers that can handle the content type of the request data when accessing request.DATA or request.FILES.

    +

    By default this exception results in a response with the HTTP status code "415 Unsupported Media Type".

    +

    Throttled

    +

    Signature: Throttled(wait=None, detail=None)

    +

    Raised when an incoming request fails the throttling checks.

    +

    By default this exception results in a response with the HTTP status code "429 Too Many Requests".

    @@ -114,5 +173,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/format-suffixes.html b/api-guide/format-suffixes.html new file mode 100644 index 000000000..52cd59936 --- /dev/null +++ b/api-guide/format-suffixes.html @@ -0,0 +1,130 @@ + + + + Django REST framework + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + +
    +

    urlpatterns.py

    +

    Format suffixes

    +
    +

    Section 6.2.1 does not say that content negotiation should be +used all the time.

    +

    — Roy Fielding, REST discuss mailing list

    +
    +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/api-guide/generic-views.html b/api-guide/generic-views.html new file mode 100644 index 000000000..21835f026 --- /dev/null +++ b/api-guide/generic-views.html @@ -0,0 +1,130 @@ + + + + Django REST framework + + + + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + +
    +

    mixins.py +generics.py

    +

    Generic views

    +
    +

    Django’s generic views... were developed as a shortcut for common usage patterns... They take certain common idioms and patterns found in view development and abstract them so that you can quickly write common views of data without having to repeat yourself.

    +

    Django Documentation

    +
    +
    +
    +
    + + + + + + + + + + \ No newline at end of file diff --git a/api-guide/parsers.html b/api-guide/parsers.html index 315abfab7..72396b0ae 100644 --- a/api-guide/parsers.html +++ b/api-guide/parsers.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -116,5 +119,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/permissions.html b/api-guide/permissions.html index 31d09b551..bd33c122f 100644 --- a/api-guide/permissions.html +++ b/api-guide/permissions.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -89,6 +92,14 @@
    @@ -97,6 +108,59 @@

    permissions.py

    Permissions

    +
    +

    Authentication or identification by itself is not usually sufficient to gain access to information or code. For that, the entity requesting access must have authorization.

    +

    Apple Developer Documentation

    +
    +

    Together with authentication and throttling, permissions determine wheter a request should be granted or denied access.

    +

    Permission checks are always run at the very start of the view, before any other code is allowed to proceed. Permission checks will typically use the authentication information in the request.user and request.auth properties to determine if the incoming request should be permitted.

    +

    How permissions are determined

    +

    Permissions in REST framework are always defined as a list of permission classes. Before running the main body of the view, each permission in the list is checked.

    +

    If any permission check fails an exceptions.PermissionDenied exception will be raised, and the main body of the view will not run.

    +

    Object level permissions

    +

    REST framework permissions also support object-level permissioning. Object level permissions are used to determine if a user should be allowed to act on a particular object, which will typically be a model instance.

    +

    Object level permissions are run by REST framework's generic views when .get_object() is called. As with view level permissions, an exceptions.PermissionDenied exception will be raised if the user is not allowed to act on the given object.

    +

    Setting the permission policy

    +

    The default permission policy may be set globally, using the DEFAULT_PERMISSIONS setting. For example.

    +
    API_SETTINGS = {
    +    'DEFAULT_PERMISSIONS': (
    +        'djangorestframework.permissions.IsAuthenticated',
    +    )
    +}
    +
    +

    You can also set the authentication policy on a per-view basis, using the APIView class based views.

    +
    class ExampleView(APIView):
    +    permission_classes = (IsAuthenticated,)
    +
    +    def get(self, request, format=None):
    +        content = {
    +            'status': 'request was permitted'
    +        }
    +        return Response(content)
    +
    +

    Or, if you're using the @api_view decorator with function based views.

    +
    @api_view('GET')
    +@permission_classes(IsAuthenticated)
    +def example_view(request, format=None):
    +    content = {
    +        'status': 'request was permitted'
    +    }
    +    return Response(content)
    +
    +

    IsAuthenticated

    +

    The IsAuthenticated permission class will deny permission to any unauthenticated user, and allow permission otherwise.

    +

    This permission is suitable if you want your API to only be accessible to registered users.

    +

    IsAdminUser

    +

    The IsAdminUser permission class will deny permission to any user, unless user.is_staffis True in which case permission will be allowed.

    +

    This permission is suitable is you want your API to only be accessible to a subset of trusted administrators.

    +

    IsAuthenticatedOrReadOnly

    +

    The IsAuthenticatedOrReadOnly will allow authenticated users to perform any request. Requests for unauthorised users will only be permitted if the request method is one of the "safe" methods; GET, HEAD or OPTIONS.

    +

    This permission is suitable if you want to your API to allow read permissions to anonymous users, and only allow write permissions to authenticated users.

    +

    DjangoModelPermissions

    +

    This permission class ties into Django's standard django.contrib.auth model permissions. When applied to a view that has a .model property, permission will only be granted if the user

    +

    Custom permissions

    +

    To implement a custom permission, override BasePermission and implement the .check_permission(self, request, obj=None) method.

    +

    The method should return True if the request should be granted access, and False otherwise.

    @@ -114,5 +178,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/renderers.html b/api-guide/renderers.html index 56fef3c83..1d6112c16 100644 --- a/api-guide/renderers.html +++ b/api-guide/renderers.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -116,5 +119,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/requests.html b/api-guide/requests.html index dd858d8a6..596100f7c 100644 --- a/api-guide/requests.html +++ b/api-guide/requests.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -157,5 +160,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/responses.html b/api-guide/responses.html index f738ee835..c4379c50b 100644 --- a/api-guide/responses.html +++ b/api-guide/responses.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -129,5 +132,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/reverse.html b/api-guide/reverse.html index 06e29f371..7be8aa95a 100644 --- a/api-guide/reverse.html +++ b/api-guide/reverse.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -88,7 +91,7 @@
    @@ -112,8 +115,12 @@

    settings.py

    Settings

    -

    Configuration for REST framework is all namespaced inside the API_SETTINGS setting.

    -

    For example your project's settings.py file might look like this:

    +
    +

    Namespaces are one honking great idea - let's do more of those!

    +

    The Zen of Python

    +
    +

    Configuration for REST framework is all namespaced inside a single Django setting, named API_SETTINGS.

    +

    For example your project's settings.py file might include something like this:

    API_SETTINGS = {
         'DEFAULT_RENDERERS': (
             'djangorestframework.renderers.YAMLRenderer',
    @@ -210,5 +217,9 @@ print api_settings.DEFAULT_AUTHENTICATION
           var shiftWindow = function() { scrollBy(0, -50) };
           if (location.hash) shiftWindow();
           window.addEventListener("hashchange", shiftWindow);
    +
    +      $('.dropdown-menu').click(function(event) {
    +        event.stopPropagation();
    +      });
         
     
    \ No newline at end of file
    diff --git a/api-guide/status-codes.html b/api-guide/status-codes.html
    index b1d9a91bd..73fd184fb 100644
    --- a/api-guide/status-codes.html
    +++ b/api-guide/status-codes.html
    @@ -47,15 +47,18 @@
                       
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -193,5 +196,9 @@ HTTP_511_NETWORD_AUTHENTICATION_REQUIRED var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/throttling.html b/api-guide/throttling.html index 639690fc8..3e150d269 100644 --- a/api-guide/throttling.html +++ b/api-guide/throttling.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -89,6 +92,9 @@ @@ -97,6 +103,13 @@

    throttling.py

    Throttling

    +
    +

    HTTP/1.1 420 Enhance Your Calm

    +

    Twitter API rate limiting response

    +
    +

    PerUserThrottle

    +

    PerViewThrottle

    +

    Custom throttles

    @@ -114,5 +127,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/api-guide/views.html b/api-guide/views.html index a872d7b34..2818c8d5e 100644 --- a/api-guide/views.html +++ b/api-guide/views.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -148,5 +151,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/css/drf-styles.css b/css/drf-styles.css index bb31b07cb..a5f0b97a2 100644 --- a/css/drf-styles.css +++ b/css/drf-styles.css @@ -14,15 +14,6 @@ pre { font-size: 12px; } -a.github { - float: right; - margin-top: -12px; -} - -a.github:hover { - text-decoration: none; -} - .dropdown .dropdown-menu { display: none; } @@ -31,25 +22,38 @@ a.github:hover { display: block; } +/* GitHub 'Star' badge */ body.index #main-content iframe { float: right; -} - -body.index #main-content iframe { - float: right; + margin-top: -12px; margin-right: -15px; } +/* Travis CI badge */ body.index #main-content p:first-of-type { float: right; margin-right: 8px; - margin-top: -1px; + margin-top: -14px; + margin-bottom: 0px; } +/* Github source file badges */ +a.github { + float: right; + margin-top: -12px; + margin-right: 12px; +} + +a.github:hover { + text-decoration: none; +} + +/* Force TOC text to not overrun */ #table-of-contents { overflow: hidden; } +/* Code blocks should scroll horizontally */ pre { overflow: auto; word-wrap: normal; @@ -71,13 +75,10 @@ pre { } } - .nav-list li.main { font-weight: bold; } - - /* Set the table of contents to static so it flows back into the content when viewed on tablets and smaller. */ @media (max-width: 767px) { @@ -94,7 +95,7 @@ pre { } } - +/* Cutesy quote styling */ blockquote { font-family: Georgia, serif; font-size: 18px; diff --git a/index.html b/index.html index e8cd3da69..8ee99a975 100644 --- a/index.html +++ b/index.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -166,15 +169,18 @@ pip install -r optionals.txt
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • Topics

    @@ -230,5 +236,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

    var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/topics/contributing.html b/topics/contributing.html index f9a011a38..bd8fbc26f 100644 --- a/topics/contributing.html +++ b/topics/contributing.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -118,5 +121,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/topics/credits.html b/topics/credits.html index 298225879..1c965399d 100644 --- a/topics/credits.html +++ b/topics/credits.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -167,5 +170,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/topics/csrf.html b/topics/csrf.html index 5b635dbd1..487764403 100644 --- a/topics/csrf.html +++ b/topics/csrf.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -122,5 +125,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/topics/formoverloading.html b/topics/formoverloading.html index 20e25a0e5..005343c8a 100644 --- a/topics/formoverloading.html +++ b/topics/formoverloading.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -141,5 +144,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/tutorial/1-serialization.html b/tutorial/1-serialization.html index b38139cdf..7e6231609 100644 --- a/tutorial/1-serialization.html +++ b/tutorial/1-serialization.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -328,5 +331,9 @@ urlpatterns = patterns('blog.views', var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/tutorial/2-requests-and-responses.html b/tutorial/2-requests-and-responses.html index 5ca0d97d3..9a5b0d2f5 100644 --- a/tutorial/2-requests-and-responses.html +++ b/tutorial/2-requests-and-responses.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -228,5 +231,9 @@ urlpatterns = format_suffix_patterns(urlpatterns) var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/tutorial/3-class-based-views.html b/tutorial/3-class-based-views.html index a2b55931e..620f3f536 100644 --- a/tutorial/3-class-based-views.html +++ b/tutorial/3-class-based-views.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -244,5 +247,9 @@ comment_instance = CommentInstance.as_view() var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/tutorial/4-authentication-permissions-and-throttling.html b/tutorial/4-authentication-permissions-and-throttling.html index 04d510119..3e4206335 100644 --- a/tutorial/4-authentication-permissions-and-throttling.html +++ b/tutorial/4-authentication-permissions-and-throttling.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -112,5 +115,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/tutorial/5-relationships-and-hyperlinked-apis.html b/tutorial/5-relationships-and-hyperlinked-apis.html index 24b1afedb..18c580a7e 100644 --- a/tutorial/5-relationships-and-hyperlinked-apis.html +++ b/tutorial/5-relationships-and-hyperlinked-apis.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -118,5 +121,9 @@ var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file diff --git a/tutorial/6-resource-orientated-projects.html b/tutorial/6-resource-orientated-projects.html index da8d8ccb4..a6f543998 100644 --- a/tutorial/6-resource-orientated-projects.html +++ b/tutorial/6-resource-orientated-projects.html @@ -47,15 +47,18 @@
  • Requests
  • Responses
  • Views
  • +
  • Generic views
  • Parsers
  • Renderers
  • Serializers
  • Authentication
  • Permissions
  • Throttling
  • +
  • Content negotiation
  • +
  • Format suffixes
  • +
  • Returning URLs
  • Exceptions
  • Status codes
  • -
  • Returning URLs
  • Settings
  • @@ -155,5 +158,9 @@ urlpatterns = router.urlpatterns var shiftWindow = function() { scrollBy(0, -50) }; if (location.hash) shiftWindow(); window.addEventListener("hashchange", shiftWindow); + + $('.dropdown-menu').click(function(event) { + event.stopPropagation(); + }); \ No newline at end of file