From e5c8c6ea50c3efa5efcfe313a8b852c1284695c0 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 13:07:16 +0100 Subject: [PATCH] Change package name: djangorestframework -> rest_framework --- api-guide/authentication.html | 16 +++++------ api-guide/content-negotiation.html | 2 +- api-guide/exceptions.html | 2 +- api-guide/format-suffixes.html | 2 +- api-guide/generic-views.html | 4 +-- api-guide/parsers.html | 2 +- api-guide/permissions.html | 6 ++-- api-guide/renderers.html | 2 +- api-guide/requests.html | 6 ++-- api-guide/responses.html | 2 +- api-guide/reverse.html | 6 ++-- api-guide/serializers.html | 2 +- api-guide/settings.html | 30 ++++++++++---------- api-guide/status-codes.html | 4 +-- api-guide/throttling.html | 14 ++++----- api-guide/views.html | 2 +- index.html | 9 +++--- topics/browsable-api.html | 4 +-- topics/credits.html | 1 + tutorial/1-serialization.html | 14 ++++----- tutorial/2-requests-and-responses.html | 8 +++--- tutorial/3-class-based-views.html | 14 ++++----- tutorial/6-resource-orientated-projects.html | 2 +- 23 files changed, 78 insertions(+), 76 deletions(-) diff --git a/api-guide/authentication.html b/api-guide/authentication.html index e3be9b1e3..23fb3bc55 100644 --- a/api-guide/authentication.html +++ b/api-guide/authentication.html @@ -107,7 +107,7 @@
-

authentication.py

+

authentication.py

Authentication

Auth needs to be pluggable.

@@ -124,10 +124,10 @@

The value of request.user and request.auth for unauthenticated requests can be modified using the UNAUTHENTICATED_USER and UNAUTHENTICATED_TOKEN settings.

Setting the authentication policy

The default authentication policy may be set globally, using the DEFAULT_AUTHENTICATION setting. For example.

-
API_SETTINGS = {
+
REST_FRAMEWORK = {
     'DEFAULT_AUTHENTICATION': (
-        'djangorestframework.authentication.UserBasicAuthentication',
-        'djangorestframework.authentication.SessionAuthentication',
+        'rest_framework.authentication.UserBasicAuthentication',
+        'rest_framework.authentication.SessionAuthentication',
     )
 }
 
@@ -164,9 +164,9 @@ def example_view(request, format=None):

Note: If you use BasicAuthentication in production you must ensure that your API is only available over 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.

TokenAuthentication

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

-

To use the TokenAuthentication policy, include djangorestframework.authtoken in your INSTALLED_APPS setting.

+

To use the TokenAuthentication policy, include rest_framework.authtoken in your INSTALLED_APPS setting.

You'll also need to create tokens for your users.

-
from djangorestframework.authtoken.models import Token
+
from rest_framework.authtoken.models import Token
 
 token = Token.objects.create(user=...)
 print token.key
@@ -177,7 +177,7 @@ print token.key
 

If successfully authenticated, TokenAuthentication provides the following credentials.

  • request.user will be a django.contrib.auth.models.User instance.
  • -
  • request.auth will be a djangorestframework.tokenauth.models.BasicToken instance.
  • +
  • request.auth will be a rest_framework.tokenauth.models.BasicToken instance.

Note: If you use TokenAuthentication in production you must ensure that your API is only available over https only.

OAuthAuthentication

@@ -185,7 +185,7 @@ print token.key

If successfully authenticated, OAuthAuthentication provides the following credentials.

  • request.user will be a django.contrib.auth.models.User instance.
  • -
  • request.auth will be a djangorestframework.models.OAuthToken instance.
  • +
  • request.auth will be a rest_framework.models.OAuthToken instance.

SessionAuthentication

This policy uses Django's default session backend for authentication. Session authentication is appropriate for AJAX clients that are running in the same session context as your website.

diff --git a/api-guide/content-negotiation.html b/api-guide/content-negotiation.html index 443fd78c3..668cbce45 100644 --- a/api-guide/content-negotiation.html +++ b/api-guide/content-negotiation.html @@ -100,7 +100,7 @@
-

negotiation.py

+

negotiation.py

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.

diff --git a/api-guide/exceptions.html b/api-guide/exceptions.html index 61c98e1b5..de17aef0a 100644 --- a/api-guide/exceptions.html +++ b/api-guide/exceptions.html @@ -107,7 +107,7 @@
-

exceptions.py

+

exceptions.py

Exceptions

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

diff --git a/api-guide/format-suffixes.html b/api-guide/format-suffixes.html index 6920f24a1..a43aae2fb 100644 --- a/api-guide/format-suffixes.html +++ b/api-guide/format-suffixes.html @@ -100,7 +100,7 @@
-

urlpatterns.py

+

urlpatterns.py

Format suffixes

Section 6.2.1 does not say that content negotiation should be diff --git a/api-guide/generic-views.html b/api-guide/generic-views.html index f3c3631a9..8537062b5 100644 --- a/api-guide/generic-views.html +++ b/api-guide/generic-views.html @@ -100,8 +100,8 @@

-

mixins.py -generics.py

+

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.

diff --git a/api-guide/parsers.html b/api-guide/parsers.html index 6c029e501..08d5bf8da 100644 --- a/api-guide/parsers.html +++ b/api-guide/parsers.html @@ -101,7 +101,7 @@
-

parsers.py

+

parsers.py

Parsers

.parse(request)

diff --git a/api-guide/permissions.html b/api-guide/permissions.html index 7130511a9..d92224afd 100644 --- a/api-guide/permissions.html +++ b/api-guide/permissions.html @@ -108,7 +108,7 @@
-

permissions.py

+

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.

@@ -126,9 +126,9 @@ If any permission check fails an exceptions.PermissionDenied except

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 = {
+
REST_FRAMEWORK = {
     'DEFAULT_PERMISSIONS': (
-        'djangorestframework.permissions.IsAuthenticated',
+        'rest_framework.permissions.IsAuthenticated',
     )
 }
 
diff --git a/api-guide/renderers.html b/api-guide/renderers.html index 119cb82e0..7a1347f4d 100644 --- a/api-guide/renderers.html +++ b/api-guide/renderers.html @@ -101,7 +101,7 @@
-

renderers.py

+

renderers.py

Renderers

.render(response)

diff --git a/api-guide/requests.html b/api-guide/requests.html index 203dad4f2..bfe7acbd6 100644 --- a/api-guide/requests.html +++ b/api-guide/requests.html @@ -109,7 +109,7 @@
-

request.py

+

request.py

Requests

If you're doing REST-based web service stuff ... you should ignore request.POST.

@@ -137,14 +137,14 @@

.parsers

request.parsers should be set to a list of Parser instances that can be used to parse the content of the request body.

request.parsers may no longer be altered once request.DATA, request.FILES or request.POST have been accessed.

-

If you're using the djangorestframework.views.View class... [TODO]

+

If you're using the rest_framework.views.View class... [TODO]

.stream

request.stream returns a stream representing the content of the request body.

You will not typically need to access request.stream, unless you're writing a Parser class.

.authentication

request.authentication should be set to a list of Authentication instances that can be used to authenticate the request.

request.authentication may no longer be altered once request.user or request.auth have been accessed.

-

If you're using the djangorestframework.views.View class... [TODO]

+

If you're using the rest_framework.views.View class... [TODO]

diff --git a/api-guide/responses.html b/api-guide/responses.html index 31a4eef51..7486a9631 100644 --- a/api-guide/responses.html +++ b/api-guide/responses.html @@ -104,7 +104,7 @@
-

response.py

+

response.py

Responses

Unlike basic HttpResponse objects, TemplateResponse objects retain the details of the context that was provided by the view to compute the response. The final output of the response is not computed until it is needed, later in the response process.

diff --git a/api-guide/reverse.html b/api-guide/reverse.html index 1a93dcac7..48c6152b9 100644 --- a/api-guide/reverse.html +++ b/api-guide/reverse.html @@ -102,7 +102,7 @@
-

reverse.py

+

reverse.py

Returning URLs

The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components.

@@ -120,8 +120,8 @@

There's no requirement for you to use them, but if you do then the self-describing API will be able to automatically hyperlink it's output for you, which makes browsing the API much easier.

reverse(viewname, request, args, *kwargs)

Has the same behavior as django.core.urlresolvers.reverse, except that it returns a fully qualified URL, using the request to determine the host and port.

-
from djangorestframework.utils import reverse
-from djangorestframework.views import APIView
+
from rest_framework.utils import reverse
+from rest_framework.views import APIView
 
 class MyView(APIView):
     def get(self, request):
diff --git a/api-guide/serializers.html b/api-guide/serializers.html
index a2dbae281..bbbab7c1b 100644
--- a/api-guide/serializers.html
+++ b/api-guide/serializers.html
@@ -112,7 +112,7 @@
         
-

serializers.py

+

serializers.py

Serializers

Expanding the usefulness of the serializers is something that we would diff --git a/api-guide/settings.html b/api-guide/settings.html index 871923b22..900dfdc89 100644 --- a/api-guide/settings.html +++ b/api-guide/settings.html @@ -115,27 +115,27 @@

-

settings.py

+

settings.py

Settings

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.

+

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

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

-
API_SETTINGS = {
+
REST_FRAMEWORK = {
     'DEFAULT_RENDERERS': (
-        'djangorestframework.renderers.YAMLRenderer',
+        'rest_framework.renderers.YAMLRenderer',
     )
     'DEFAULT_PARSERS': (
-        'djangorestframework.parsers.YAMLParser',
+        'rest_framework.parsers.YAMLParser',
     )
 }
 

Accessing settings

If you need to access the values of REST framework's API settings in your project, you should use the api_settings object. For example.

-
from djangorestframework.settings import api_settings
+
from rest_framework.settings import api_settings
 
 print api_settings.DEFAULT_AUTHENTICATION
 
@@ -144,25 +144,25 @@ print api_settings.DEFAULT_AUTHENTICATION

A list or tuple of renderer classes, that determines the default set of renderers that may be used when returning a Response object.

Default:

(
-    'djangorestframework.renderers.JSONRenderer',
-    'djangorestframework.renderers.DocumentingHTMLRenderer'
-    'djangorestframework.renderers.TemplateHTMLRenderer'
+    'rest_framework.renderers.JSONRenderer',
+    'rest_framework.renderers.DocumentingHTMLRenderer'
+    'rest_framework.renderers.TemplateHTMLRenderer'
 )
 

DEFAULT_PARSERS

A list or tuple of parser classes, that determines the default set of parsers used when accessing the request.DATA property.

Default:

(
-    'djangorestframework.parsers.JSONParser',
-    'djangorestframework.parsers.FormParser'
+    'rest_framework.parsers.JSONParser',
+    'rest_framework.parsers.FormParser'
 )
 

DEFAULT_AUTHENTICATION

A list or tuple of authentication classes, that determines the default set of authenticators used when accessing the request.user or request.auth properties.

Default:

(
-    'djangorestframework.authentication.SessionAuthentication',
-    'djangorestframework.authentication.UserBasicAuthentication'
+    'rest_framework.authentication.SessionAuthentication',
+    'rest_framework.authentication.UserBasicAuthentication'
 )
 

DEFAULT_PERMISSIONS

@@ -173,10 +173,10 @@ print api_settings.DEFAULT_AUTHENTICATION

Default: ()

DEFAULT_MODEL_SERIALIZER

TODO

-

Default: djangorestframework.serializers.ModelSerializer

+

Default: rest_framework.serializers.ModelSerializer

DEFAULT_PAGINATION_SERIALIZER

TODO

-

Default: djangorestframework.pagination.PaginationSerializer

+

Default: rest_framework.pagination.PaginationSerializer

FORMAT_SUFFIX_KWARG

TODO

Default: 'format'

diff --git a/api-guide/status-codes.html b/api-guide/status-codes.html index ef372fce2..216691737 100644 --- a/api-guide/status-codes.html +++ b/api-guide/status-codes.html @@ -105,14 +105,14 @@
-

status.py

+

status.py

Status Codes

418 I'm a teapot - Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout.

RFC 2324, Hyper Text Coffee Pot Control Protocol

Using bare status codes in your responses isn't recommended. REST framework includes a set of named constants that you can use to make more code more obvious and readable.

-
from djangorestframework import status
+
from rest_framework import status
 
 def empty_view(self):
     content = {'please move along': 'nothing to see here'}
diff --git a/api-guide/throttling.html b/api-guide/throttling.html
index fd4fff608..5ff2e7092 100644
--- a/api-guide/throttling.html
+++ b/api-guide/throttling.html
@@ -106,7 +106,7 @@
         
-

throttling.py

+

throttling.py

Throttling

HTTP/1.1 420 Enhance Your Calm

@@ -123,10 +123,10 @@ If any throttle check fails an exceptions.Throttled exception will be raised, and the main body of the view will not run.

Setting the throttling policy

The default throttling policy may be set globally, using the DEFAULT_THROTTLES and DEFAULT_THROTTLE_RATES settings. For example.

-
API_SETTINGS = {
+
REST_FRAMEWORK = {
     'DEFAULT_THROTTLES': (
-        'djangorestframework.throttles.AnonThrottle',
-        'djangorestframework.throttles.UserThrottle',
+        'rest_framework.throttles.AnonThrottle',
+        'rest_framework.throttles.UserThrottle',
     )
     'DEFAULT_THROTTLE_RATES': {
         'anon': '100/day',
@@ -178,7 +178,7 @@ class SustainedRateThrottle(UserRateThrottle):
     scope = 'sustained'
 

...and the following settings.

-
API_SETTINGS = {
+
REST_FRAMEWORK = {
     'DEFAULT_THROTTLES': (
         'example.throttles.BurstRateThrottle',
         'example.throttles.SustainedRateThrottle',
@@ -207,9 +207,9 @@ class UploadView(APIView):
     ...
 

...and the following settings.

-
API_SETTINGS = {
+
REST_FRAMEWORK = {
     'DEFAULT_THROTTLES': (
-        'djangorestframework.throttles.ScopedRateThrottle',
+        'rest_framework.throttles.ScopedRateThrottle',
     )
     'DEFAULT_THROTTLE_RATES': {
         'contacts': '1000/day',
diff --git a/api-guide/views.html b/api-guide/views.html
index 620e0621f..e33d08501 100644
--- a/api-guide/views.html
+++ b/api-guide/views.html
@@ -110,7 +110,7 @@
         
-

views.py

+

views.py

Views

Django's class based views are a welcome departure from the old-style views.

diff --git a/index.html b/index.html index 801050ff9..6df00f0ad 100644 --- a/index.html +++ b/index.html @@ -140,18 +140,19 @@ cd django-rest-framework pip install -r requirements.txt pip install -r optionals.txt
-

Add djangorestframework to your INSTALLED_APPS.

+

Add rest_framework to your INSTALLED_APPS.

INSTALLED_APPS = (
     ...
-    'djangorestframework',        
+    'rest_framework',        
 )
 

If you're intending to use the browserable API you'll want to add REST framework's login and logout views. Add the following to your root urls.py file.

urlpatterns = patterns('',
     ...
-    url(r'^api-auth/', include('djangorestframework.urls', namespace='djangorestframework'))
+    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
 )
 
+

Note that the base URL can be whatever you want, but you must include rest_framework.urls with the rest_framework namespace.

Quickstart

TODO

Tutorial

@@ -199,7 +200,7 @@ pip install -r optionals.txt
./mkdocs.py
 

Run the tests:

-
./djangorestframework/runtests/runtests.py
+
./rest_framework/runtests/runtests.py
 

License

Copyright (c) 2011-2012, Tom Christie diff --git a/topics/browsable-api.html b/topics/browsable-api.html index d69958b14..93eeebf48 100644 --- a/topics/browsable-api.html +++ b/topics/browsable-api.html @@ -106,11 +106,11 @@

Working with the Browsable API

API may stand for Application Programming Interface, but humans have to be able to read the APIs, too; someone has to do the programming. Django REST Framework supports generating human-friendly HTML output for each resource when the HTML format is requested. These pages allow for easy browsing of resources, as well as forms for submitting data to the resources using POST, PUT, and DELETE.

URLs

-

If you include fully-qualified URLs in your resource output, they will be 'urlized' and made clickable for easy browsing by humans. The djangorestframework package includes a reverse helper for this purpose.

+

If you include fully-qualified URLs in your resource output, they will be 'urlized' and made clickable for easy browsing by humans. The rest_framework package includes a reverse helper for this purpose.

Formats

By default, the API will return the format specified by the headers, which in the case of the browser is HTML. The format can be specified using ?format= in the request, so you can look at the raw JSON response in a browser by adding ?format=json to the URL. There are helpful extensions for viewing JSON in Firefox and Chrome.

Customizing

-

To customize the look-and-feel, create a template called api.html and add it to your project, eg: templates/djangorestframework/api.html, that extends the djangorestframework/base.html template.

+

To customize the look-and-feel, create a template called api.html and add it to your project, eg: templates/rest_framework/api.html, that extends the rest_framework/base.html template.

The included browsable API template is built with Bootstrap (2.1.1), making it easy to customize the look-and-feel.

Theme

To replace the theme wholesale, add a bootstrap_theme block to your api.html and insert a link to the desired Bootstrap theme css file. This will completely replace the included theme.

diff --git a/topics/credits.html b/topics/credits.html index 76da1d1e5..c89081c5b 100644 --- a/topics/credits.html +++ b/topics/credits.html @@ -143,6 +143,7 @@
  • Can Yavuz - tschan
  • Shawn Lewis - shawnlewis
  • Alec Perkins - alecperkins
  • +
  • Michael Barrett - phobologic
  • Many thanks to everyone who's contributed to the project.

    Additional thanks

    diff --git a/tutorial/1-serialization.html b/tutorial/1-serialization.html index 01b71c2dd..2ffaf5126 100644 --- a/tutorial/1-serialization.html +++ b/tutorial/1-serialization.html @@ -145,10 +145,10 @@ cd tutorial } }
    -

    We'll also need to add our new blog app and the djangorestframework app to INSTALLED_APPS.

    +

    We'll also need to add our new blog app and the rest_framework app to INSTALLED_APPS.

    INSTALLED_APPS = (
         ...
    -    'djangorestframework',
    +    'rest_framework',
         'blog'
     )
     
    @@ -173,7 +173,7 @@ class Comment(models.Model):

    Creating a Serializer class

    We're going to create a simple Web API that we can use to edit these comment objects with. The first thing we need is a way of serializing and deserializing the objects into representations such as json. We do this by declaring serializers, that work very similarly to Django's forms. Create a file in the project named serializers.py and add the following.

    from blog import models
    -from djangorestframework import serializers
    +from rest_framework import serializers
     
     class CommentSerializer(serializers.Serializer):
         email = serializers.EmailField()
    @@ -201,8 +201,8 @@ class CommentSerializer(serializers.Serializer):
     

    Okay, once we've got a few imports out of the way, we'd better create a few comments to work with.

    from blog.models import Comment
     from blog.serializers import CommentSerializer
    -from djangorestframework.renderers import JSONRenderer
    -from djangorestframework.parsers import JSONParser
    +from rest_framework.renderers import JSONRenderer
    +from rest_framework.parsers import JSONParser
     
     c1 = Comment(email='leila@example.com', content='nothing to say')
     c2 = Comment(email='tom@example.com', content='foo bar')
    @@ -238,8 +238,8 @@ We'll start off by creating a subclass of HttpResponse that we can use to render
     

    Edit the blog/views.py file, and add the following.

    from blog.models import Comment
     from blog.serializers import CommentSerializer
    -from djangorestframework.renderers import JSONRenderer
    -from djangorestframework.parsers import JSONParser
    +from rest_framework.renderers import JSONRenderer
    +from rest_framework.parsers import JSONParser
     from django.http import HttpResponse
     
     class JSONResponse(HttpResponse):
    diff --git a/tutorial/2-requests-and-responses.html b/tutorial/2-requests-and-responses.html
    index 82011802a..9e0170702 100644
    --- a/tutorial/2-requests-and-responses.html
    +++ b/tutorial/2-requests-and-responses.html
    @@ -135,9 +135,9 @@ request.DATA  # Handles arbitrary data.  Works any HTTP request with content.
     

    We don't need our JSONResponse class anymore, so go ahead and delete that. Once that's done we can start refactoring our views slightly.

    from blog.models import Comment
     from blog.serializers import CommentSerializer
    -from djangorestframework import status
    -from djangorestframework.decorators import api_view
    -from djangorestframework.response import Response
    +from rest_framework import status
    +from rest_framework.decorators import api_view
    +from rest_framework.response import Response
     
     @api_view(['GET', 'POST'])
     def comment_root(request):
    @@ -198,7 +198,7 @@ def comment_instance(request, pk):
     

    Now update the urls.py file slightly, to append a set of format_suffix_patterns in addition to the existing URLs.

    from django.conf.urls import patterns, url
    -from djangorestframework.urlpatterns import format_suffix_patterns
    +from rest_framework.urlpatterns import format_suffix_patterns
     
     urlpatterns = patterns('blogpost.views',
         url(r'^$', 'comment_root'),
    diff --git a/tutorial/3-class-based-views.html b/tutorial/3-class-based-views.html
    index 5621f93f9..89aa03687 100644
    --- a/tutorial/3-class-based-views.html
    +++ b/tutorial/3-class-based-views.html
    @@ -110,9 +110,9 @@
     
    from blog.models import Comment
     from blog.serializers import CommentSerializer
     from django.http import Http404
    -from djangorestframework.views import APIView
    -from djangorestframework.response import Response
    -from djangorestframework import status
    +from rest_framework.views import APIView
    +from rest_framework.response import Response
    +from rest_framework import status
     
     class CommentRoot(APIView):
         """
    @@ -165,7 +165,7 @@ class CommentRoot(APIView):
     

    That's looking good. Again, it's still pretty similar to the function based view right now.

    We'll also need to refactor our URLconf slightly now we're using class based views.

    from django.conf.urls import patterns, url
    -from djangorestframework.urlpatterns import format_suffix_patterns
    +from rest_framework.urlpatterns import format_suffix_patterns
     from blogpost import views
     
     urlpatterns = patterns('',
    @@ -182,8 +182,8 @@ urlpatterns = format_suffix_patterns(urlpatterns)
     

    Let's take a look at how we can compose our views by using the mixin classes.

    from blog.models import Comment
     from blog.serializers import CommentSerializer
    -from djangorestframework import mixins
    -from djangorestframework import generics
    +from rest_framework import mixins
    +from rest_framework import generics
     
     class CommentRoot(mixins.ListModelMixin,
                       mixins.CreateModelMixin,
    @@ -220,7 +220,7 @@ class CommentRoot(mixins.ListModelMixin,
     

    Using the mixin classes we've rewritten the views to use slightly less code than before, but we can go one step further. REST framework provides a set of already mixed-in generic views that we can use.

    from blog.models import Comment
     from blog.serializers import CommentSerializer
    -from djangorestframework import generics
    +from rest_framework import generics
     
     class CommentRoot(generics.RootAPIView):
         model = Comment
    diff --git a/tutorial/6-resource-orientated-projects.html b/tutorial/6-resource-orientated-projects.html
    index 29d92f5f8..62ed50f9f 100644
    --- a/tutorial/6-resource-orientated-projects.html
    +++ b/tutorial/6-resource-orientated-projects.html
    @@ -149,7 +149,7 @@ urlpatterns = patterns('blogpost.views',
     

    Using Routers

    Right now that hasn't really saved us a lot of code. However, now that we're using Resources rather than Views, we actually don't need to design the urlconf ourselves. The conventions for wiring up resources into views and urls can be handled automatically, using Router classes. All we need to do is register the appropriate resources with a router, and let it do the rest. Here's our re-wired urls.py file.

    from blog import resources
    -from djangorestframework.routers import DefaultRouter
    +from rest_framework.routers import DefaultRouter
     
     router = DefaultRouter()
     router.register(resources.BlogPostResource)