aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.txt20
-rw-r--r--djangorestframework/__init__.py (renamed from flywheel/__init__.py)0
-rw-r--r--djangorestframework/authenticators.py (renamed from flywheel/authenticators.py)0
-rw-r--r--djangorestframework/emitters.py (renamed from flywheel/emitters.py)8
-rw-r--r--djangorestframework/modelresource.py (renamed from flywheel/modelresource.py)42
-rw-r--r--djangorestframework/parsers.py (renamed from flywheel/parsers.py)2
-rw-r--r--djangorestframework/resource.py (renamed from flywheel/resource.py)4
-rw-r--r--djangorestframework/response.py (renamed from flywheel/response.py)0
-rw-r--r--djangorestframework/templates/emitter.html (renamed from flywheel/templates/emitter.html)0
-rw-r--r--djangorestframework/templates/emitter.txt (renamed from flywheel/templates/emitter.txt)0
-rw-r--r--djangorestframework/templatetags/__init__.py (renamed from flywheel/templatetags/__init__.py)0
-rw-r--r--djangorestframework/templatetags/add_query_param.py (renamed from flywheel/templatetags/add_query_param.py)0
-rw-r--r--djangorestframework/templatetags/urlize_quoted_links.py (renamed from flywheel/templatetags/urlize_quoted_links.py)2
-rw-r--r--djangorestframework/utils.py (renamed from flywheel/utils.py)0
-rw-r--r--docs/conf.py2
-rw-r--r--docs/index.rst28
-rw-r--r--docs/requirements.txt8
-rw-r--r--examples/blogpost/views.py6
-rw-r--r--examples/objectstore/views.py4
-rw-r--r--examples/pygments_api/views.py6
-rw-r--r--examples/requirements.txt6
-rw-r--r--examples/settings.py9
-rw-r--r--examples/simpleexample/__init__.py0
-rw-r--r--examples/simpleexample/models.py23
-rw-r--r--examples/simpleexample/urls.py6
-rw-r--r--examples/simpleexample/views.py18
-rw-r--r--examples/urls.py27
-rw-r--r--requirements.txt2
28 files changed, 155 insertions, 68 deletions
diff --git a/README.txt b/README.txt
index 44e4f96d..784713b6 100644
--- a/README.txt
+++ b/README.txt
@@ -1,17 +1,21 @@
-# To install django-rest-framework...
-#
-# Requirements:
-# python2.6
-# virtualenv
+# To install django-rest-framework in a virtualenv environment...
hg clone https://tomchristie@bitbucket.org/tomchristie/django-rest-framework
cd django-rest-framework/
virtualenv --no-site-packages --distribute --python=python2.6 env
source ./env/bin/activate
-pip install -r ./requirements.txt
-python ./src/manage.py test
+pip install -r requirements.txt
# To build the documentation...
-sphinx-build -c docs -b html -d cache docs html
+pip install -r docs/requirements.txt
+sphinx-build -c docs -b html -d docs-build docs html
+
+# To run the examples...
+
+pip install -r examples/requirements.txt
+cd examples
+export PYTHONPATH=..
+python manage.py syncdb
+python manage.py runserver
diff --git a/flywheel/__init__.py b/djangorestframework/__init__.py
index e69de29b..e69de29b 100644
--- a/flywheel/__init__.py
+++ b/djangorestframework/__init__.py
diff --git a/flywheel/authenticators.py b/djangorestframework/authenticators.py
index 8de182de..8de182de 100644
--- a/flywheel/authenticators.py
+++ b/djangorestframework/authenticators.py
diff --git a/flywheel/emitters.py b/djangorestframework/emitters.py
index f548e1d9..a69407f1 100644
--- a/flywheel/emitters.py
+++ b/djangorestframework/emitters.py
@@ -1,5 +1,5 @@
"""Emitters are used to serialize a Resource's output into specific media types.
-FlyWheel also provides HTML and PlainText emitters that help self-document the API,
+django-rest-framework also provides HTML and PlainText emitters that help self-document the API,
by serializing the output along with documentation regarding the Resource, output status and headers,
and providing forms and links depending on the allowed methods, emitters and parsers on the Resource.
"""
@@ -7,8 +7,8 @@ from django.conf import settings
from django.template import RequestContext, loader
from django import forms
-from flywheel.response import NoContent
-from flywheel.utils import dict2xml, url_resolves
+from djangorestframework.response import NoContent
+from djangorestframework.utils import dict2xml, url_resolves
from urllib import quote_plus
import string
@@ -193,7 +193,7 @@ class XMLEmitter(BaseEmitter):
class DocumentingHTMLEmitter(DocumentingTemplateEmitter):
"""Emitter which provides a browsable HTML interface for an API.
- See the examples listed in the FlyWheel documentation to see this in actions."""
+ See the examples listed in the django-rest-framework documentation to see this in actions."""
media_type = 'text/html'
template = 'emitter.html'
diff --git a/flywheel/modelresource.py b/djangorestframework/modelresource.py
index d68ec79e..a9605d4a 100644
--- a/flywheel/modelresource.py
+++ b/djangorestframework/modelresource.py
@@ -2,8 +2,8 @@ from django.forms import ModelForm
from django.db.models.query import QuerySet
from django.db.models import Model
-from flywheel.response import status, Response, ResponseException
-from flywheel.resource import Resource
+from djangorestframework.response import status, Response, ResponseException
+from djangorestframework.resource import Resource
import decimal
import inspect
@@ -336,28 +336,41 @@ class ModelResource(Resource):
return _any(data, self.fields)
- def post(self, request, content, *args, **kwargs):
+ def post(self, request, auth, content, *args, **kwargs):
# TODO: test creation on a non-existing resource url
all_kw_args = dict(content.items() + kwargs.items())
- instance = self.model(**all_kw_args)
+ if args:
+ instance = self.model(pk=args[-1], **all_kw_args)
+ else:
+ instance = self.model(**all_kw_args)
instance.save()
headers = {}
if hasattr(instance, 'get_absolute_url'):
headers['Location'] = self.add_domain(instance.get_absolute_url())
return Response(status.HTTP_201_CREATED, instance, headers)
- def get(self, request, *args, **kwargs):
+ def get(self, request, auth, *args, **kwargs):
try:
- instance = self.model.objects.get(**kwargs)
+ if args:
+ # If we have any none kwargs then assume the last represents the primrary key
+ instance = self.model.objects.get(pk=args[-1], **kwargs)
+ else:
+ # Otherwise assume the kwargs uniquely identify the model
+ instance = self.model.objects.get(**kwargs)
except self.model.DoesNotExist:
raise ResponseException(status.HTTP_404_NOT_FOUND)
return instance
- def put(self, request, content, *args, **kwargs):
+ def put(self, request, auth, content, *args, **kwargs):
# TODO: update on the url of a non-existing resource url doesn't work correctly at the moment - will end up with a new url
try:
- instance = self.model.objects.get(**kwargs)
+ if args:
+ # If we have any none kwargs then assume the last represents the primrary key
+ instance = self.model.objects.get(pk=args[-1], **kwargs)
+ else:
+ # Otherwise assume the kwargs uniquely identify the model
+ instance = self.model.objects.get(**kwargs)
for (key, val) in content.items():
setattr(instance, key, val)
except self.model.DoesNotExist:
@@ -367,9 +380,14 @@ class ModelResource(Resource):
instance.save()
return instance
- def delete(self, request, *args, **kwargs):
+ def delete(self, request, auth, *args, **kwargs):
try:
- instance = self.model.objects.get(**kwargs)
+ if args:
+ # If we have any none kwargs then assume the last represents the primrary key
+ instance = self.model.objects.get(pk=args[-1], **kwargs)
+ else:
+ # Otherwise assume the kwargs uniquely identify the model
+ instance = self.model.objects.get(**kwargs)
except self.model.DoesNotExist:
raise ResponseException(status.HTTP_404_NOT_FOUND, None, {})
@@ -382,7 +400,7 @@ class RootModelResource(ModelResource):
allowed_methods = ('GET', 'POST')
queryset = None
- def get(self, request, *args, **kwargs):
+ def get(self, request, auth, *args, **kwargs):
queryset = self.queryset if self.queryset else self.model.objects.all()
return queryset
@@ -396,7 +414,7 @@ class QueryModelResource(ModelResource):
def get_form(self, data=None):
return None
- def get(self, request, *args, **kwargs):
+ def get(self, request, auth, *args, **kwargs):
queryset = self.queryset if self.queryset else self.model.objects.all()
return queryset
diff --git a/flywheel/parsers.py b/djangorestframework/parsers.py
index 98232a96..a656e2eb 100644
--- a/flywheel/parsers.py
+++ b/djangorestframework/parsers.py
@@ -1,4 +1,4 @@
-from flywheel.response import status, ResponseException
+from djangorestframework.response import status, ResponseException
try:
import json
diff --git a/flywheel/resource.py b/djangorestframework/resource.py
index 2a8554f3..d06d51b0 100644
--- a/flywheel/resource.py
+++ b/djangorestframework/resource.py
@@ -2,8 +2,8 @@ from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.http import HttpResponse
-from flywheel import emitters, parsers, authenticators
-from flywheel.response import status, Response, ResponseException
+from djangorestframework import emitters, parsers, authenticators
+from djangorestframework.response import status, Response, ResponseException
from decimal import Decimal
import re
diff --git a/flywheel/response.py b/djangorestframework/response.py
index 4f23bb0a..4f23bb0a 100644
--- a/flywheel/response.py
+++ b/djangorestframework/response.py
diff --git a/flywheel/templates/emitter.html b/djangorestframework/templates/emitter.html
index d21350cd..d21350cd 100644
--- a/flywheel/templates/emitter.html
+++ b/djangorestframework/templates/emitter.html
diff --git a/flywheel/templates/emitter.txt b/djangorestframework/templates/emitter.txt
index 1cc7d1d7..1cc7d1d7 100644
--- a/flywheel/templates/emitter.txt
+++ b/djangorestframework/templates/emitter.txt
diff --git a/flywheel/templatetags/__init__.py b/djangorestframework/templatetags/__init__.py
index e69de29b..e69de29b 100644
--- a/flywheel/templatetags/__init__.py
+++ b/djangorestframework/templatetags/__init__.py
diff --git a/flywheel/templatetags/add_query_param.py b/djangorestframework/templatetags/add_query_param.py
index 91c1a312..91c1a312 100644
--- a/flywheel/templatetags/add_query_param.py
+++ b/djangorestframework/templatetags/add_query_param.py
diff --git a/flywheel/templatetags/urlize_quoted_links.py b/djangorestframework/templatetags/urlize_quoted_links.py
index 60088cf6..eea424a4 100644
--- a/flywheel/templatetags/urlize_quoted_links.py
+++ b/djangorestframework/templatetags/urlize_quoted_links.py
@@ -97,4 +97,4 @@ urlize_quoted_links.is_safe = True
# Register urlize_quoted_links as a custom filter
# http://docs.djangoproject.com/en/dev/howto/custom-template-tags/
register = template.Library()
-register.filter(urlize_quoted_links) \ No newline at end of file
+register.filter(urlize_quoted_links)
diff --git a/flywheel/utils.py b/djangorestframework/utils.py
index f9bbc0fe..f9bbc0fe 100644
--- a/flywheel/utils.py
+++ b/djangorestframework/utils.py
diff --git a/docs/conf.py b/docs/conf.py
index 71cacb3d..3689a636 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -14,7 +14,7 @@
import sys, os
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'flywheel'))
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'djangorestframework'))
sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(__file__)), 'examples'))
import settings
from django.core.management import setup_environ
diff --git a/docs/index.rst b/docs/index.rst
index 7a871a5c..7da3f017 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -26,10 +26,10 @@ Requirements
Installation & Setup
--------------------
-The django-rest-framework project is hosted as a `mercurial repository on bitbucket <https://bitbucket.org/tomchristie/flywheel>`_.
+The django-rest-framework project is hosted as a `mercurial repository on bitbucket <https://bitbucket.org/tomchristie/django-rest-framework>`_.
To get a local copy of the repository use mercurial::
- hg clone https://tomchristie@bitbucket.org/tomchristie/flywheel
+ hg clone https://tomchristie@bitbucket.org/tomchristie/django-rest-framework
To add django-rest-framework to a django project:
@@ -43,27 +43,15 @@ Getting Started
Often you'll want parts of your API to directly map to existing Models.
At it's simplest this looks something like this...
-``views.py``::
+``urls.py``
- from djangorestframework.modelresource import ModelResource, ModelRootResource
- from models import MyModel
+.. include:: ../examples/simpleexample/urls.py
+ :literal:
- class MyModelRootResource(ModelRootResource):
- """A create/list resource for MyModel."""
- allowed_methods = ('GET', 'POST')
- model = MyModel
+``views.py``
- class MyModelResource(ModelResource):
- """A read/update/delete resource for MyModel."""
- allowed_methods = ('GET', 'PUT', 'DELETE')
- model = MyModel
-
-``urls.py``::
-
- urlpatterns += patterns('myapp.views',
- url(r'^mymodel/$', 'MyModelRootResource'),
- url(r'^mymodel/([^/]+)/$', 'MyModelResource'),
- )
+.. include:: ../examples/simpleexample/views.py
+ :literal:
Examples
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..77cdf485
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,8 @@
+# Documentation requires Django & Sphinx, and their dependencies...
+
+Django==1.2.4
+Jinja2==2.5.5
+Pygments==1.4
+Sphinx==1.0.7
+docutils==0.7
+wsgiref==0.1.2
diff --git a/examples/blogpost/views.py b/examples/blogpost/views.py
index c5be2544..bfb53b5d 100644
--- a/examples/blogpost/views.py
+++ b/examples/blogpost/views.py
@@ -1,6 +1,6 @@
-from flywheel.response import Response, status
-from flywheel.resource import Resource
-from flywheel.modelresource import ModelResource, RootModelResource
+from djangorestframework.response import Response, status
+from djangorestframework.resource import Resource
+from djangorestframework.modelresource import ModelResource, RootModelResource
from blogpost.models import BlogPost, Comment
BLOG_POST_FIELDS = ('created', 'title', 'slug', 'content', 'absolute_url', 'comment_url', 'comments_url')
diff --git a/examples/objectstore/views.py b/examples/objectstore/views.py
index 4681fe70..90bdb9e3 100644
--- a/examples/objectstore/views.py
+++ b/examples/objectstore/views.py
@@ -1,7 +1,7 @@
from django.conf import settings
-from flywheel.resource import Resource
-from flywheel.response import Response, status
+from djangorestframework.resource import Resource
+from djangorestframework.response import Response, status
import pickle
import os
diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py
index d9082ada..e22705d9 100644
--- a/examples/pygments_api/views.py
+++ b/examples/pygments_api/views.py
@@ -1,8 +1,8 @@
from django.conf import settings
-from flywheel.resource import Resource
-from flywheel.response import Response, status
-from flywheel.emitters import BaseEmitter
+from djangorestframework.resource import Resource
+from djangorestframework.response import Response, status
+from djangorestframework.emitters import BaseEmitter
from pygments.formatters import HtmlFormatter
from pygments.lexers import get_lexer_by_name
diff --git a/examples/requirements.txt b/examples/requirements.txt
new file mode 100644
index 00000000..4ae9e3c7
--- /dev/null
+++ b/examples/requirements.txt
@@ -0,0 +1,6 @@
+# For the examples we need Django, pygments and httplib2...
+
+Django==1.2.4
+wsgiref==0.1.2
+Pygments==1.4
+httplib2==0.6.0
diff --git a/examples/settings.py b/examples/settings.py
index 0ae3bf56..4aa5dd00 100644
--- a/examples/settings.py
+++ b/examples/settings.py
@@ -93,9 +93,10 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
- 'django.contrib.admin',
- 'flywheel',
- 'blogpost',
+ #'django.contrib.admin',
+ 'djangorestframework',
+ 'simpleexample',
'objectstore',
- 'pygments_api'
+ 'pygments_api',
+ 'blogpost',
)
diff --git a/examples/simpleexample/__init__.py b/examples/simpleexample/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/examples/simpleexample/__init__.py
diff --git a/examples/simpleexample/models.py b/examples/simpleexample/models.py
new file mode 100644
index 00000000..13867f61
--- /dev/null
+++ b/examples/simpleexample/models.py
@@ -0,0 +1,23 @@
+from django.db import models
+
+MAX_INSTANCES = 20
+
+class MyModel(models.Model):
+ foo = models.BooleanField()
+ bar = models.IntegerField(help_text='Must be an integer.')
+ baz = models.CharField(max_length=32, help_text='Free text. Max length 32 chars.')
+ created = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ ordering = ('created',)
+
+ def save(self, *args, **kwargs):
+ """For the purposes of the sandbox, limit the maximum number of stored models."""
+ while MyModel.objects.all().count() > MAX_INSTANCES:
+ MyModel.objects.all()[0].delete()
+ super(MyModel, self).save(*args, **kwargs)
+
+ @models.permalink
+ def get_absolute_url(self):
+ return ('simpleexample.views.MyModelResource', (self.pk,))
+
diff --git a/examples/simpleexample/urls.py b/examples/simpleexample/urls.py
new file mode 100644
index 00000000..d853ba5a
--- /dev/null
+++ b/examples/simpleexample/urls.py
@@ -0,0 +1,6 @@
+from django.conf.urls.defaults import patterns, url
+
+urlpatterns = patterns('simpleexample.views',
+ url(r'^$', 'MyModelRootResource'),
+ url(r'^([0-9]+)/$', 'MyModelResource'),
+)
diff --git a/examples/simpleexample/views.py b/examples/simpleexample/views.py
new file mode 100644
index 00000000..1f113ac2
--- /dev/null
+++ b/examples/simpleexample/views.py
@@ -0,0 +1,18 @@
+from djangorestframework.modelresource import ModelResource, RootModelResource
+from simpleexample.models import MyModel
+
+FIELDS = ('foo', 'bar', 'baz', 'absolute_url')
+
+class MyModelRootResource(RootModelResource):
+ """A create/list resource for MyModel.
+ Available for both authenticated and anonymous access for the purposes of the sandbox."""
+ model = MyModel
+ allowed_methods = anon_allowed_methods = ('GET', 'POST')
+ fields = FIELDS
+
+class MyModelResource(ModelResource):
+ """A read/update/delete resource for MyModel.
+ Available for both authenticated and anonymous access for the purposes of the sandbox."""
+ model = MyModel
+ allowed_methods = anon_allowed_methods = ('GET', 'PUT', 'DELETE')
+ fields = FIELDS
diff --git a/examples/urls.py b/examples/urls.py
index b1dec13d..2b8e6fcd 100644
--- a/examples/urls.py
+++ b/examples/urls.py
@@ -1,14 +1,27 @@
from django.conf.urls.defaults import patterns, include
-from django.contrib import admin
+#from django.contrib import admin
+from djangorestframework.resource import Resource
+
+#admin.autodiscover()
+
+class RootResource(Resource):
+ allowed_methods = anon_allowed_methods = ('GET',)
+
+ def get(self, request, auth):
+ return {'simple example': self.reverse('simpleexample.views.MyModelRootResource'),
+ 'pygments example': self.reverse('pygments_api.views.PygmentsRoot'),
+ 'object store example': self.reverse('objectstore.views.ObjectStoreRoot'),
+ 'blog post example': self.reverse('blogpost.views.BlogPostRoot'),}
-admin.autodiscover()
urlpatterns = patterns('',
- (r'^pygments-example/', include('pygments_api.urls')),
- (r'^blog-post-example/', include('blogpost.urls')),
- (r'^object-store-example/', include('objectstore.urls')),
+ (r'^$', RootResource),
+ (r'^simple-example/', include('simpleexample.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'^admin/doc/', include('django.contrib.admindocs.urls')),
+ #(r'^admin/', include(admin.site.urls)),
)
diff --git a/requirements.txt b/requirements.txt
index 8144d828..84f0c4eb 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,5 @@
+# Django and pip are required if installing into a virtualenv environment...
+
Django==1.2.4
distribute==0.6.14
wsgiref==0.1.2