diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/blogpost/models.py | 8 | ||||
| -rw-r--r-- | examples/blogpost/urls.py | 13 | ||||
| -rw-r--r-- | examples/blogpost/views.py | 22 | ||||
| -rw-r--r-- | examples/mixin/__init__.py | 0 | ||||
| -rw-r--r-- | examples/mixin/urls.py | 23 | ||||
| -rw-r--r-- | examples/modelresourceexample/models.py | 2 | ||||
| -rw-r--r-- | examples/modelresourceexample/urls.py | 5 | ||||
| -rw-r--r-- | examples/objectstore/urls.py | 9 | ||||
| -rw-r--r-- | examples/objectstore/views.py | 9 | ||||
| -rw-r--r-- | examples/pygments_api/urls.py | 9 | ||||
| -rw-r--r-- | examples/pygments_api/views.py | 6 | ||||
| -rw-r--r-- | examples/requirements.txt | 2 | ||||
| -rw-r--r-- | examples/resourceexample/urls.py | 7 | ||||
| -rw-r--r-- | examples/resourceexample/views.py | 5 | ||||
| -rw-r--r-- | examples/sandbox/__init__.py | 0 | ||||
| -rw-r--r-- | examples/sandbox/views.py | 35 | ||||
| -rw-r--r-- | examples/settings.py | 17 | ||||
| -rw-r--r-- | examples/templates/base.html | 7 | ||||
| -rw-r--r-- | examples/templates/registration/login.html | 26 | ||||
| -rw-r--r-- | examples/urls.py | 40 | 
20 files changed, 133 insertions, 112 deletions
| diff --git a/examples/blogpost/models.py b/examples/blogpost/models.py index e1968415..c85ca788 100644 --- a/examples/blogpost/models.py +++ b/examples/blogpost/models.py @@ -24,13 +24,13 @@ class BlogPost(models.Model):      @models.permalink      def get_absolute_url(self): -        return ('blogpost.views.BlogPostInstance', (), {'key': self.key}) +        return ('blog-post', (), {'key': self.key})      @property      @models.permalink      def comments_url(self):          """Link to a resource which lists all comments for this blog post.""" -        return ('blogpost.views.CommentRoot', (), {'blogpost_id': self.key}) +        return ('comments', (), {'blogpost_id': self.key})      def __unicode__(self):          return self.title @@ -52,11 +52,11 @@ class Comment(models.Model):      @models.permalink      def get_absolute_url(self): -        return ('blogpost.views.CommentInstance', (), {'blogpost': self.blogpost.key, 'id': self.id}) +        return ('comment', (), {'blogpost': self.blogpost.key, 'id': self.id})      @property      @models.permalink      def blogpost_url(self):          """Link to the blog post resource which this comment corresponds to.""" -        return ('blogpost.views.BlogPostInstance', (), {'key': self.blogpost.key}) +        return ('blog-post', (), {'key': self.blogpost.key}) diff --git a/examples/blogpost/urls.py b/examples/blogpost/urls.py index ee209b3e..b2df96a1 100644 --- a/examples/blogpost/urls.py +++ b/examples/blogpost/urls.py @@ -1,8 +1,9 @@ -from django.conf.urls.defaults import patterns +from django.conf.urls.defaults import patterns, url +from blogpost.views import BlogPosts, BlogPostInstance, Comments, CommentInstance -urlpatterns = patterns('blogpost.views', -    (r'^$', 'BlogPostRoot'), -    (r'^(?P<key>[^/]+)/$', 'BlogPostInstance'), -    (r'^(?P<blogpost_id>[^/]+)/comments/$', 'CommentRoot'), -    (r'^(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', 'CommentInstance'), +urlpatterns = patterns('', +    url(r'^$', BlogPosts.as_view(), name='blog-posts'), +    url(r'^(?P<key>[^/]+)/$', BlogPostInstance.as_view(), name='blog-post'), +    url(r'^(?P<blogpost_id>[^/]+)/comments/$', Comments.as_view(), name='comments'), +    url(r'^(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', CommentInstance.as_view(), name='comment'),  ) diff --git a/examples/blogpost/views.py b/examples/blogpost/views.py index bfb53b5d..0377b447 100644 --- a/examples/blogpost/views.py +++ b/examples/blogpost/views.py @@ -1,33 +1,33 @@  from djangorestframework.response import Response, status  from djangorestframework.resource import Resource  from djangorestframework.modelresource import ModelResource, RootModelResource -from blogpost.models import BlogPost, Comment +from blogpost import models  BLOG_POST_FIELDS = ('created', 'title', 'slug', 'content', 'absolute_url', 'comment_url', 'comments_url')  COMMENT_FIELDS = ('username', 'comment', 'created', 'rating', 'absolute_url', 'blogpost_url') -class BlogPostRoot(RootModelResource): +class BlogPosts(RootModelResource):      """A resource with which lists all existing blog posts and creates new blog posts.""" -    allowed_methods = ('GET', 'POST',) -    model = BlogPost +    anon_allowed_methods = allowed_methods = ('GET', 'POST',) +    model = models.BlogPost      fields = BLOG_POST_FIELDS  class BlogPostInstance(ModelResource):      """A resource which represents a single blog post.""" -    allowed_methods = ('GET', 'PUT', 'DELETE') -    model = BlogPost +    anon_allowed_methods = allowed_methods = ('GET', 'PUT', 'DELETE') +    model = models.BlogPost      fields = BLOG_POST_FIELDS -class CommentRoot(RootModelResource): +class Comments(RootModelResource):      """A resource which lists all existing comments for a given blog post, and creates new blog comments for a given blog post.""" -    allowed_methods = ('GET', 'POST',) -    model = Comment +    anon_allowed_methods = allowed_methods = ('GET', 'POST',) +    model = models.Comment      fields = COMMENT_FIELDS  class CommentInstance(ModelResource):      """A resource which represents a single comment.""" -    allowed_methods = ('GET', 'PUT', 'DELETE') -    model = Comment +    anon_allowed_methods = allowed_methods = ('GET', 'PUT', 'DELETE') +    model = models.Comment      fields = COMMENT_FIELDS diff --git a/examples/mixin/__init__.py b/examples/mixin/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/examples/mixin/__init__.py diff --git a/examples/mixin/urls.py b/examples/mixin/urls.py new file mode 100644 index 00000000..05009284 --- /dev/null +++ b/examples/mixin/urls.py @@ -0,0 +1,23 @@ +from djangorestframework.compat import View  # Use Django 1.3's django.views.generic.View, or fall back to a clone of that if Django < 1.3  +from djangorestframework.emitters import EmitterMixin, DEFAULT_EMITTERS +from djangorestframework.response import Response + +from django.conf.urls.defaults import patterns, url +from django.core.urlresolvers import reverse + + +class ExampleView(EmitterMixin, View): +    """An example view using Django 1.3's class based views. +    Uses djangorestframework's EmitterMixin to provide support for multiple output formats.""" +    emitters = DEFAULT_EMITTERS + +    def get(self, request): +        response = Response(200, {'description': 'Some example content', +                                  'url': reverse('mixin-view')}) +        return self.emit(response) + + +urlpatterns = patterns('', +    url(r'^$', ExampleView.as_view(), name='mixin-view'), +) + diff --git a/examples/modelresourceexample/models.py b/examples/modelresourceexample/models.py index 036501d0..16047524 100644 --- a/examples/modelresourceexample/models.py +++ b/examples/modelresourceexample/models.py @@ -19,5 +19,5 @@ class MyModel(models.Model):      @models.permalink      def get_absolute_url(self): -        return ('modelresourceexample.views.MyModelResource', (self.pk,)) +        return ('my-model-resource', (self.pk,)) diff --git a/examples/modelresourceexample/urls.py b/examples/modelresourceexample/urls.py index c43cf56a..53d950cd 100644 --- a/examples/modelresourceexample/urls.py +++ b/examples/modelresourceexample/urls.py @@ -1,6 +1,7 @@  from django.conf.urls.defaults import patterns, url +from modelresourceexample.views import MyModelRootResource, MyModelResource  urlpatterns = patterns('modelresourceexample.views', -    url(r'^$',          'MyModelRootResource'), -    url(r'^([0-9]+)/$', 'MyModelResource'), +    url(r'^$',          MyModelRootResource.as_view(), name='my-model-root-resource'), +    url(r'^([0-9]+)/$', MyModelResource.as_view(), name='my-model-resource'),  ) diff --git a/examples/objectstore/urls.py b/examples/objectstore/urls.py index c04e731e..2c685f59 100644 --- a/examples/objectstore/urls.py +++ b/examples/objectstore/urls.py @@ -1,6 +1,7 @@ -from django.conf.urls.defaults import patterns - +from django.conf.urls.defaults import patterns, url +from objectstore.views import ObjectStoreRoot, StoredObject +   urlpatterns = patterns('objectstore.views', -    (r'^$', 'ObjectStoreRoot'),  -    (r'^(?P<key>[A-Za-z0-9_-]{1,64})/$', 'StoredObject'), +    url(r'^$', ObjectStoreRoot.as_view(), name='object-store-root'),  +    url(r'^(?P<key>[A-Za-z0-9_-]{1,64})/$', StoredObject.as_view(), name='stored-object'),  ) diff --git a/examples/objectstore/views.py b/examples/objectstore/views.py index e1b239dc..b3ed5533 100644 --- a/examples/objectstore/views.py +++ b/examples/objectstore/views.py @@ -1,4 +1,5 @@  from django.conf import settings +from django.core.urlresolvers import reverse  from djangorestframework.resource import Resource  from djangorestframework.response import Response, status @@ -29,7 +30,7 @@ class ObjectStoreRoot(Resource):      def get(self, request, auth):          """Return a list of all the stored object URLs."""          keys = sorted(os.listdir(OBJECT_STORE_DIR)) -        return [self.reverse(StoredObject, key=key) for key in keys] +        return [reverse('stored-object', kwargs={'key':key}) for key in keys]      def post(self, request, auth, content):          """Create a new stored object, with a unique key.""" @@ -37,9 +38,9 @@ class ObjectStoreRoot(Resource):          pathname = os.path.join(OBJECT_STORE_DIR, key)          pickle.dump(content, open(pathname, 'wb'))          remove_oldest_files(OBJECT_STORE_DIR, MAX_FILES) -        return Response(status.HTTP_201_CREATED, content, {'Location': self.reverse(StoredObject, key=key)}) -  -         +        return Response(status.HTTP_201_CREATED, content, {'Location': reverse('stored-object', kwargs={'key':key})}) + +  class StoredObject(Resource):      """Represents a stored object.      The object may be any picklable content.""" diff --git a/examples/pygments_api/urls.py b/examples/pygments_api/urls.py index f96f4518..905e31c5 100644 --- a/examples/pygments_api/urls.py +++ b/examples/pygments_api/urls.py @@ -1,6 +1,7 @@ -from django.conf.urls.defaults import patterns +from django.conf.urls.defaults import patterns, url +from pygments_api.views import PygmentsRoot, PygmentsInstance -urlpatterns = patterns('pygments_api.views', -    (r'^$', 'PygmentsRoot'),  -    (r'^([a-zA-Z0-9-]+)/$', 'PygmentsInstance'), +urlpatterns = patterns('', +    url(r'^$', PygmentsRoot.as_view(), name='pygments-root'),  +    url(r'^([a-zA-Z0-9-]+)/$', PygmentsInstance.as_view(), name='pygments-instance'),  ) diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py index e22705d9..84e5e703 100644 --- a/examples/pygments_api/views.py +++ b/examples/pygments_api/views.py @@ -1,4 +1,6 @@ +from __future__ import with_statement  # for python 2.5  from django.conf import settings +from django.core.urlresolvers import reverse  from djangorestframework.resource import Resource  from djangorestframework.response import Response, status @@ -41,7 +43,7 @@ class PygmentsRoot(Resource):      def get(self, request, auth):          """Return a list of all currently existing snippets."""          unique_ids = sorted(os.listdir(HIGHLIGHTED_CODE_DIR)) -        return [self.reverse(PygmentsInstance, unique_id) for unique_id in unique_ids] +        return [reverse('pygments-instance', args=[unique_id]) for unique_id in unique_ids]      def post(self, request, auth, content):          """Create a new highlighed snippet and return it's location. @@ -59,7 +61,7 @@ class PygmentsRoot(Resource):          remove_oldest_files(HIGHLIGHTED_CODE_DIR, MAX_FILES) -        return Response(status.HTTP_201_CREATED, headers={'Location': self.reverse(PygmentsInstance, unique_id)}) +        return Response(status.HTTP_201_CREATED, headers={'Location': reverse('pygments-instance', args=[unique_id])})  class PygmentsInstance(Resource): diff --git a/examples/requirements.txt b/examples/requirements.txt index 4ae9e3c7..09cda945 100644 --- a/examples/requirements.txt +++ b/examples/requirements.txt @@ -4,3 +4,5 @@ Django==1.2.4  wsgiref==0.1.2  Pygments==1.4  httplib2==0.6.0 +Markdown==2.0.3 + diff --git a/examples/resourceexample/urls.py b/examples/resourceexample/urls.py index 828caef2..cb6435bb 100644 --- a/examples/resourceexample/urls.py +++ b/examples/resourceexample/urls.py @@ -1,6 +1,7 @@  from django.conf.urls.defaults import patterns, url +from resourceexample.views import ExampleResource, AnotherExampleResource -urlpatterns = patterns('resourceexample.views', -    url(r'^$',                 'ExampleResource'), -    url(r'^(?P<num>[0-9]+)/$', 'AnotherExampleResource'), +urlpatterns = patterns('', +    url(r'^$',                 ExampleResource.as_view(), name='example-resource'), +    url(r'^(?P<num>[0-9]+)/$', AnotherExampleResource.as_view(), name='another-example-resource'),  ) diff --git a/examples/resourceexample/views.py b/examples/resourceexample/views.py index e5bb5efa..c4462ee2 100644 --- a/examples/resourceexample/views.py +++ b/examples/resourceexample/views.py @@ -1,13 +1,14 @@ +from django.core.urlresolvers import reverse  from djangorestframework.resource import Resource  from djangorestframework.response import Response, status  from resourceexample.forms import MyForm  class ExampleResource(Resource): -    """A basic read only resource that points to 3 other resources.""" +    """A basic read-only resource that points to 3 other resources."""      allowed_methods = anon_allowed_methods = ('GET',)      def get(self, request, auth): -        return {"Some other resources": [self.reverse(AnotherExampleResource, num=num) for num in range(3)]} +        return {"Some other resources": [reverse('another-example-resource', kwargs={'num':num}) for num in range(3)]}  class AnotherExampleResource(Resource):      """A basic GET-able/POST-able resource.""" diff --git a/examples/sandbox/__init__.py b/examples/sandbox/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/examples/sandbox/__init__.py diff --git a/examples/sandbox/views.py b/examples/sandbox/views.py new file mode 100644 index 00000000..561bdb1d --- /dev/null +++ b/examples/sandbox/views.py @@ -0,0 +1,35 @@ +"""The root view for the examples provided with Django REST framework""" + +from django.core.urlresolvers import reverse +from djangorestframework.resource import Resource + + +class Sandbox(Resource): +    """This is the sandbox for the examples provided with [Django REST framework](http://django-rest-framework.org). + +    These examples are provided to help you get a better idea of the some of the features of RESTful APIs created using the framework. + +    All the example APIs allow anonymous access, and can be navigated either through the browser or from the command line... + +        bash: curl -X GET http://api.django-rest-framework.org/                           # (Use default emitter) +        bash: curl -X GET http://api.django-rest-framework.org/ -H 'Accept: text/plain'   # (Use plaintext documentation emitter) + +    The examples provided:  +    +    1. A basic example using the [Resource](http://django-rest-framework.org/library/resource.html) class. +    2. A basic example using the [ModelResource](http://django-rest-framework.org/library/modelresource.html) class. +    3. An basic example using Django 1.3's [class based views](http://docs.djangoproject.com/en/dev/topics/class-based-views/) and djangorestframework's [EmitterMixin](http://django-rest-framework.org/library/emitters.html). +    4. A generic object store API. +    5. A code highlighting API. +    6. A blog posts and comments API. + +    Please feel free to browse, create, edit and delete the resources in these examples.""" +    allowed_methods = anon_allowed_methods = ('GET',) + +    def get(self, request, auth): +        return [{'name': 'Simple Resource example', 'url': reverse('example-resource')}, +                {'name': 'Simple ModelResource example', 'url': reverse('my-model-root-resource')}, +                {'name': 'Simple Mixin-only example', 'url': reverse('mixin-view')}, +                {'name': 'Object store API', 'url': reverse('object-store-root')}, +                {'name': 'Code highlighting API', 'url': reverse('pygments-root')}, +                {'name': 'Blog posts API', 'url': reverse('blog-posts')}] diff --git a/examples/settings.py b/examples/settings.py index 865dc394..c4cdd992 100644 --- a/examples/settings.py +++ b/examples/settings.py @@ -1,7 +1,4 @@ -# Django settings for src project. -import os - -BASE_DIR = os.path.dirname(__file__) +# Settings for djangorestframework examples project  DEBUG = True  TEMPLATE_DEBUG = DEBUG @@ -48,17 +45,23 @@ USE_L10N = True  # Absolute filesystem path to the directory that will hold user-uploaded files.  # Example: "/home/media/media.lawrence.com/" +# NOTE: Some of the djangorestframework examples use MEDIA_ROOT to store content.  MEDIA_ROOT = 'media/'  # URL that handles the media served from MEDIA_ROOT. Make sure to use a  # trailing slash if there is a path component (optional in other cases).  # Examples: "http://media.lawrence.com", "http://example.com/media/" +# NOTE: None of the djangorestframework examples serve media content via MEDIA_URL.   MEDIA_URL = ''  # URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a  # trailing slash.  # Examples: "http://foo.com/media/", "/media/". -ADMIN_MEDIA_PREFIX = '/media/' +# NOTE: djangorestframework does not require the admin app to be installed, +# but it does require the admin media be served.  Django's test server will do +# this for you automatically, but in production you'll want to make sure you +# serve the admin media from somewhere. +ADMIN_MEDIA_PREFIX = '/admin-media/'  # Make this unique, and don't share it with anybody.  SECRET_KEY = 't&9mru2_k$t8e2-9uq-wu2a1)9v*us&j3i#lsqkt(lbx*vh1cu' @@ -84,16 +87,16 @@ TEMPLATE_DIRS = (      # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".      # Always use forward slashes, even on Windows.      # Don't forget to use absolute paths, not relative paths. -    os.path.join(BASE_DIR, 'templates')  ) +  INSTALLED_APPS = (      'django.contrib.auth',      'django.contrib.contenttypes',      'django.contrib.sessions',      'django.contrib.sites',      'django.contrib.messages', -    #'django.contrib.admin', +      'djangorestframework',      'resourceexample', diff --git a/examples/templates/base.html b/examples/templates/base.html deleted file mode 100644 index 1ff37dab..00000000 --- a/examples/templates/base.html +++ /dev/null @@ -1,7 +0,0 @@ -<html> -  <head> -  </head> -  <body> -{% block content %}{% endblock %} -  </body> -</html>
\ No newline at end of file diff --git a/examples/templates/registration/login.html b/examples/templates/registration/login.html deleted file mode 100644 index 9d0b481b..00000000 --- a/examples/templates/registration/login.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "base.html" %} - -{% block content %} - -{% if form.errors %} -<p>Your username and password didn't match. Please try again.</p> -{% endif %} - -<form method="post" action="{% url django.contrib.auth.views.login %}"> -{% csrf_token %} -<table> -<tr> -    <td>{{ form.username.label_tag }}</td> -    <td>{{ form.username }}</td> -</tr> -<tr> -    <td>{{ form.password.label_tag }}</td> -    <td>{{ form.password }}</td> -</tr> -</table> - -<input type="submit" value="login" /> -<input type="hidden" name="next" value="{{ next }}" /> -</form> - -{% endblock %}
\ No newline at end of file diff --git a/examples/urls.py b/examples/urls.py index 41b80d58..03894e4e 100644 --- a/examples/urls.py +++ b/examples/urls.py @@ -1,37 +1,19 @@ -from django.conf.urls.defaults import patterns, include -#from django.contrib import admin -from djangorestframework.resource import Resource +from django.conf.urls.defaults import patterns, include, url +from sandbox.views import Sandbox -#admin.autodiscover() +urlpatterns = patterns('djangorestframework.views', +    (r'robots.txt', 'deny_robots'), +    (r'favicon.ico', 'favicon'), -class RootResource(Resource): -    """This is the sandbox for the examples provided with django-rest-framework. +    (r'^$', Sandbox.as_view()), -    These examples are here to help you get a better idea of the some of the -    features of django-rest-framework API, such as automatic form and model validation, -    support for multiple input and output media types, etc... - -    Please feel free to browse, create, edit and delete the resources here, either -    in the browser, from the command line, or programmatically.""" -    allowed_methods = anon_allowed_methods = ('GET',) - -    def get(self, request, auth): -        return {'Simple Resource example': self.reverse('resourceexample.views.ExampleResource'), -                'Simple ModelResource example': self.reverse('modelresourceexample.views.MyModelRootResource'), -                'Object store API (Resource)': self.reverse('objectstore.views.ObjectStoreRoot'), -                'A pygments pastebin API (Resource + forms)': self.reverse('pygments_api.views.PygmentsRoot'), -                'Blog posts API (ModelResource)': self.reverse('blogpost.views.BlogPostRoot'),} - - -urlpatterns = patterns('', -    (r'^$', RootResource), -    (r'^model-resource-example/', include('modelresourceexample.urls')),      (r'^resource-example/', include('resourceexample.urls')), +    (r'^model-resource-example/', include('modelresourceexample.urls')), +    (r'^mixin/', include('mixin.urls')),      (r'^object-store/', include('objectstore.urls')),      (r'^pygments/', include('pygments_api.urls')),      (r'^blog-post/', include('blogpost.urls')), -    (r'^accounts/login/$', 'django.contrib.auth.views.login'), -    (r'^accounts/logout/$', 'django.contrib.auth.views.logout'), -    #(r'^admin/doc/', include('django.contrib.admindocs.urls')), -    #(r'^admin/', include(admin.site.urls)), + +    (r'^accounts/login/$', 'api_login'), +    (r'^accounts/logout/$', 'api_logout'),  ) | 
