mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 09:36:49 +03:00
Rename to django-rest-framework, get simpleexample working
This commit is contained in:
parent
8a470f031e
commit
42f2f9b40d
20
README.txt
20
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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
@ -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
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from flywheel.response import status, ResponseException
|
||||
from djangorestframework.response import status, ResponseException
|
||||
|
||||
try:
|
||||
import json
|
|
@ -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
|
|
@ -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)
|
||||
register.filter(urlize_quoted_links)
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
8
docs/requirements.txt
Normal file
8
docs/requirements.txt
Normal file
|
@ -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
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
6
examples/requirements.txt
Normal file
6
examples/requirements.txt
Normal file
|
@ -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
|
|
@ -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',
|
||||
)
|
||||
|
|
0
examples/simpleexample/__init__.py
Normal file
0
examples/simpleexample/__init__.py
Normal file
23
examples/simpleexample/models.py
Normal file
23
examples/simpleexample/models.py
Normal file
|
@ -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,))
|
||||
|
6
examples/simpleexample/urls.py
Normal file
6
examples/simpleexample/urls.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('simpleexample.views',
|
||||
url(r'^$', 'MyModelRootResource'),
|
||||
url(r'^([0-9]+)/$', 'MyModelResource'),
|
||||
)
|
18
examples/simpleexample/views.py
Normal file
18
examples/simpleexample/views.py
Normal file
|
@ -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
|
|
@ -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)),
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user