mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-03 05:04:31 +03:00
Remove examples (to be moved to a seperate project)
This commit is contained in:
parent
ecd3733c5e
commit
eea2aa0437
|
@ -1 +0,0 @@
|
|||
rest
|
|
@ -1,41 +0,0 @@
|
|||
from django.db import models
|
||||
from django.template.defaultfilters import slugify
|
||||
import uuid
|
||||
|
||||
|
||||
def uuid_str():
|
||||
return str(uuid.uuid1())
|
||||
|
||||
|
||||
RATING_CHOICES = ((0, 'Awful'),
|
||||
(1, 'Poor'),
|
||||
(2, 'OK'),
|
||||
(3, 'Good'),
|
||||
(4, 'Excellent'))
|
||||
|
||||
MAX_POSTS = 10
|
||||
|
||||
|
||||
class BlogPost(models.Model):
|
||||
key = models.CharField(primary_key=True, max_length=64, default=uuid_str, editable=False)
|
||||
title = models.CharField(max_length=128)
|
||||
content = models.TextField()
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
slug = models.SlugField(editable=False, default='')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
For the purposes of the sandbox, limit the maximum number of stored models.
|
||||
"""
|
||||
self.slug = slugify(self.title)
|
||||
super(self.__class__, self).save(*args, **kwargs)
|
||||
for obj in self.__class__.objects.order_by('-created')[MAX_POSTS:]:
|
||||
obj.delete()
|
||||
|
||||
|
||||
class Comment(models.Model):
|
||||
blogpost = models.ForeignKey(BlogPost, editable=False, related_name='comments')
|
||||
username = models.CharField(max_length=128)
|
||||
comment = models.TextField()
|
||||
rating = models.IntegerField(blank=True, null=True, choices=RATING_CHOICES, help_text='How did you rate this post?')
|
||||
created = models.DateTimeField(auto_now_add=True)
|
|
@ -1,36 +0,0 @@
|
|||
from djangorestframework.resources import ModelResource
|
||||
from djangorestframework.reverse import reverse
|
||||
from blogpost.models import BlogPost, Comment
|
||||
|
||||
|
||||
class BlogPostResource(ModelResource):
|
||||
"""
|
||||
A Blog Post has a *title* and *content*, and can be associated with zero or more comments.
|
||||
"""
|
||||
model = BlogPost
|
||||
fields = ('created', 'title', 'slug', 'content', 'url', 'comments')
|
||||
ordering = ('-created',)
|
||||
|
||||
def url(self, instance):
|
||||
return reverse('blog-post',
|
||||
kwargs={'key': instance.key},
|
||||
request=self.request)
|
||||
|
||||
def comments(self, instance):
|
||||
return reverse('comments',
|
||||
kwargs={'blogpost': instance.key},
|
||||
request=self.request)
|
||||
|
||||
|
||||
class CommentResource(ModelResource):
|
||||
"""
|
||||
A Comment is associated with a given Blog Post and has a *username* and *comment*, and optionally a *rating*.
|
||||
"""
|
||||
model = Comment
|
||||
fields = ('username', 'comment', 'created', 'rating', 'url', 'blogpost')
|
||||
ordering = ('-created',)
|
||||
|
||||
def blogpost(self, instance):
|
||||
return reverse('blog-post',
|
||||
kwargs={'key': instance.blogpost.key},
|
||||
request=self.request)
|
|
@ -1,210 +0,0 @@
|
|||
"""Test a range of REST API usage of the example application.
|
||||
"""
|
||||
|
||||
from django.test import TestCase
|
||||
from django.utils import simplejson as json
|
||||
|
||||
from djangorestframework.compat import RequestFactory
|
||||
from djangorestframework.reverse import reverse
|
||||
from djangorestframework.views import InstanceModelView, ListOrCreateModelView
|
||||
|
||||
from blogpost import models, urls
|
||||
#import blogpost
|
||||
|
||||
|
||||
# class AcceptHeaderTests(TestCase):
|
||||
# """Test correct behaviour of the Accept header as specified by RFC 2616:
|
||||
#
|
||||
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1"""
|
||||
#
|
||||
# def assert_accept_mimetype(self, mimetype, expect=None):
|
||||
# """Assert that a request with given mimetype in the accept header,
|
||||
# gives a response with the appropriate content-type."""
|
||||
# if expect is None:
|
||||
# expect = mimetype
|
||||
#
|
||||
# resp = self.client.get(reverse(views.RootResource), HTTP_ACCEPT=mimetype)
|
||||
#
|
||||
# self.assertEquals(resp['content-type'], expect)
|
||||
#
|
||||
#
|
||||
# def dont_test_accept_json(self):
|
||||
# """Ensure server responds with Content-Type of JSON when requested."""
|
||||
# self.assert_accept_mimetype('application/json')
|
||||
#
|
||||
# def dont_test_accept_xml(self):
|
||||
# """Ensure server responds with Content-Type of XML when requested."""
|
||||
# self.assert_accept_mimetype('application/xml')
|
||||
#
|
||||
# def dont_test_accept_json_when_prefered_to_xml(self):
|
||||
# """Ensure server responds with Content-Type of JSON when it is the client's prefered choice."""
|
||||
# self.assert_accept_mimetype('application/json;q=0.9, application/xml;q=0.1', expect='application/json')
|
||||
#
|
||||
# def dont_test_accept_xml_when_prefered_to_json(self):
|
||||
# """Ensure server responds with Content-Type of XML when it is the client's prefered choice."""
|
||||
# self.assert_accept_mimetype('application/json;q=0.1, application/xml;q=0.9', expect='application/xml')
|
||||
#
|
||||
# def dont_test_default_json_prefered(self):
|
||||
# """Ensure server responds with JSON in preference to XML."""
|
||||
# self.assert_accept_mimetype('application/json,application/xml', expect='application/json')
|
||||
#
|
||||
# def dont_test_accept_generic_subtype_format(self):
|
||||
# """Ensure server responds with an appropriate type, when the subtype is left generic."""
|
||||
# self.assert_accept_mimetype('text/*', expect='text/html')
|
||||
#
|
||||
# def dont_test_accept_generic_type_format(self):
|
||||
# """Ensure server responds with an appropriate type, when the type and subtype are left generic."""
|
||||
# self.assert_accept_mimetype('*/*', expect='application/json')
|
||||
#
|
||||
# def dont_test_invalid_accept_header_returns_406(self):
|
||||
# """Ensure server returns a 406 (not acceptable) response if we set the Accept header to junk."""
|
||||
# resp = self.client.get(reverse(views.RootResource), HTTP_ACCEPT='invalid/invalid')
|
||||
# self.assertNotEquals(resp['content-type'], 'invalid/invalid')
|
||||
# self.assertEquals(resp.status_code, 406)
|
||||
#
|
||||
# def dont_test_prefer_specific_over_generic(self): # This test is broken right now
|
||||
# """More specific accept types have precedence over less specific types."""
|
||||
# self.assert_accept_mimetype('application/xml, */*', expect='application/xml')
|
||||
# self.assert_accept_mimetype('*/*, application/xml', expect='application/xml')
|
||||
#
|
||||
#
|
||||
# class AllowedMethodsTests(TestCase):
|
||||
# """Basic tests to check that only allowed operations may be performed on a Resource"""
|
||||
#
|
||||
# def dont_test_reading_a_read_only_resource_is_allowed(self):
|
||||
# """GET requests on a read only resource should default to a 200 (OK) response"""
|
||||
# resp = self.client.get(reverse(views.RootResource))
|
||||
# self.assertEquals(resp.status_code, 200)
|
||||
#
|
||||
# def dont_test_writing_to_read_only_resource_is_not_allowed(self):
|
||||
# """PUT requests on a read only resource should default to a 405 (method not allowed) response"""
|
||||
# resp = self.client.put(reverse(views.RootResource), {})
|
||||
# self.assertEquals(resp.status_code, 405)
|
||||
#
|
||||
# def test_reading_write_only_not_allowed(self):
|
||||
# resp = self.client.get(reverse(views.WriteOnlyResource))
|
||||
# self.assertEquals(resp.status_code, 405)
|
||||
#
|
||||
# def test_writing_write_only_allowed(self):
|
||||
# resp = self.client.put(reverse(views.WriteOnlyResource), {})
|
||||
# self.assertEquals(resp.status_code, 200)
|
||||
#
|
||||
#
|
||||
#class EncodeDecodeTests(TestCase):
|
||||
# def setUp(self):
|
||||
# super(self.__class__, self).setUp()
|
||||
# self.input = {'a': 1, 'b': 'example'}
|
||||
#
|
||||
# def test_encode_form_decode_json(self):
|
||||
# content = self.input
|
||||
# resp = self.client.put(reverse(views.WriteOnlyResource), content)
|
||||
# output = json.loads(resp.content)
|
||||
# self.assertEquals(self.input, output)
|
||||
#
|
||||
# def test_encode_json_decode_json(self):
|
||||
# content = json.dumps(self.input)
|
||||
# resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json')
|
||||
# output = json.loads(resp.content)
|
||||
# self.assertEquals(self.input, output)
|
||||
#
|
||||
# #def test_encode_xml_decode_json(self):
|
||||
# # content = dict2xml(self.input)
|
||||
# # resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json', HTTP_ACCEPT='application/json')
|
||||
# # output = json.loads(resp.content)
|
||||
# # self.assertEquals(self.input, output)
|
||||
#
|
||||
# #def test_encode_form_decode_xml(self):
|
||||
# # content = self.input
|
||||
# # resp = self.client.put(reverse(views.WriteOnlyResource), content, HTTP_ACCEPT='application/xml')
|
||||
# # output = xml2dict(resp.content)
|
||||
# # self.assertEquals(self.input, output)
|
||||
#
|
||||
# #def test_encode_json_decode_xml(self):
|
||||
# # content = json.dumps(self.input)
|
||||
# # resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json', HTTP_ACCEPT='application/xml')
|
||||
# # output = xml2dict(resp.content)
|
||||
# # self.assertEquals(self.input, output)
|
||||
#
|
||||
# #def test_encode_xml_decode_xml(self):
|
||||
# # content = dict2xml(self.input)
|
||||
# # resp = self.client.put(reverse(views.WriteOnlyResource), content, 'application/json', HTTP_ACCEPT='application/xml')
|
||||
# # output = xml2dict(resp.content)
|
||||
# # self.assertEquals(self.input, output)
|
||||
#
|
||||
#class ModelTests(TestCase):
|
||||
# def test_create_container(self):
|
||||
# content = json.dumps({'name': 'example'})
|
||||
# resp = self.client.post(reverse(views.ContainerFactory), content, 'application/json')
|
||||
# output = json.loads(resp.content)
|
||||
# self.assertEquals(resp.status_code, 201)
|
||||
# self.assertEquals(output['name'], 'example')
|
||||
# self.assertEquals(set(output.keys()), set(('absolute_uri', 'name', 'key')))
|
||||
#
|
||||
#class CreatedModelTests(TestCase):
|
||||
# def setUp(self):
|
||||
# content = json.dumps({'name': 'example'})
|
||||
# resp = self.client.post(reverse(views.ContainerFactory), content, 'application/json', HTTP_ACCEPT='application/json')
|
||||
# self.container = json.loads(resp.content)
|
||||
#
|
||||
# def test_read_container(self):
|
||||
# resp = self.client.get(self.container["absolute_uri"])
|
||||
# self.assertEquals(resp.status_code, 200)
|
||||
# container = json.loads(resp.content)
|
||||
# self.assertEquals(container, self.container)
|
||||
#
|
||||
# def test_delete_container(self):
|
||||
# resp = self.client.delete(self.container["absolute_uri"])
|
||||
# self.assertEquals(resp.status_code, 204)
|
||||
# self.assertEquals(resp.content, '')
|
||||
#
|
||||
# def test_update_container(self):
|
||||
# self.container['name'] = 'new'
|
||||
# content = json.dumps(self.container)
|
||||
# resp = self.client.put(self.container["absolute_uri"], content, 'application/json')
|
||||
# self.assertEquals(resp.status_code, 200)
|
||||
# container = json.loads(resp.content)
|
||||
# self.assertEquals(container, self.container)
|
||||
|
||||
|
||||
#above testcases need to probably moved to the core
|
||||
|
||||
|
||||
class TestRotation(TestCase):
|
||||
"""For the example the maximum amount of Blogposts is capped off at views.MAX_POSTS.
|
||||
Whenever a new Blogpost is posted the oldest one should be popped."""
|
||||
|
||||
def setUp(self):
|
||||
self.factory = RequestFactory()
|
||||
models.BlogPost.objects.all().delete()
|
||||
|
||||
def test_get_to_root(self):
|
||||
'''Simple get to the *root* url of blogposts'''
|
||||
request = self.factory.get('/blog-post')
|
||||
view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource)
|
||||
response = view(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_blogposts_not_exceed_MAX_POSTS(self):
|
||||
'''Posting blog-posts should not result in more than MAX_POSTS items stored.'''
|
||||
for post in range(models.MAX_POSTS + 5):
|
||||
form_data = {'title': 'This is post #%s' % post, 'content': 'This is the content of post #%s' % post}
|
||||
request = self.factory.post('/blog-post', data=form_data)
|
||||
view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource)
|
||||
view(request)
|
||||
self.assertEquals(len(models.BlogPost.objects.all()),models.MAX_POSTS)
|
||||
|
||||
def test_fifo_behaviour(self):
|
||||
'''It's fine that the Blogposts are capped off at MAX_POSTS. But we want to make sure we see FIFO behaviour.'''
|
||||
for post in range(15):
|
||||
form_data = {'title': '%s' % post, 'content': 'This is the content of post #%s' % post}
|
||||
request = self.factory.post('/blog-post', data=form_data)
|
||||
view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource)
|
||||
view(request)
|
||||
request = self.factory.get('/blog-post')
|
||||
view = ListOrCreateModelView.as_view(resource=urls.BlogPostResource)
|
||||
response = view(request)
|
||||
response_posts = json.loads(response.content)
|
||||
response_titles = [d['title'] for d in response_posts]
|
||||
response_titles.reverse()
|
||||
self.assertEquals(response_titles, ['%s' % i for i in range(models.MAX_POSTS - 5, models.MAX_POSTS + 5)])
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
|
||||
from blogpost.resources import BlogPostResource, CommentResource
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', ListOrCreateModelView.as_view(resource=BlogPostResource), name='blog-posts-root'),
|
||||
url(r'^(?P<key>[^/]+)/$', InstanceModelView.as_view(resource=BlogPostResource), name='blog-post'),
|
||||
url(r'^(?P<blogpost>[^/]+)/comments/$', ListOrCreateModelView.as_view(resource=CommentResource), name='comments'),
|
||||
url(r'^(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', InstanceModelView.as_view(resource=CommentResource)),
|
||||
)
|
|
@ -1,62 +0,0 @@
|
|||
# This is an example epio.ini file.
|
||||
# We suggest you edit it to fit your application's needs.
|
||||
# Documentation for the options is available at www.ep.io/docs/epioini/
|
||||
|
||||
[wsgi]
|
||||
|
||||
# Location of your requirements file
|
||||
requirements = requirements-epio.txt
|
||||
|
||||
|
||||
[static]
|
||||
|
||||
# Serve the static directory directly as /static
|
||||
/static/admin = ../shortcuts/django-admin-media/
|
||||
|
||||
|
||||
[services]
|
||||
|
||||
# Uncomment to enable the PostgreSQL service.
|
||||
postgres = true
|
||||
|
||||
# Uncomment to enable the Redis service
|
||||
# redis = true
|
||||
|
||||
|
||||
[checkout]
|
||||
|
||||
# By default your code is put in a directory called 'app'.
|
||||
# You can change that here.
|
||||
# directory_name = my_project
|
||||
|
||||
|
||||
[env]
|
||||
|
||||
# Set any additional environment variables here. For example:
|
||||
# IN_PRODUCTION = true
|
||||
|
||||
|
||||
[symlinks]
|
||||
|
||||
# Any symlinks you'd like to add. As an example, link the symlink 'config.py'
|
||||
# to the real file 'configs/epio.py':
|
||||
# config.py = configs/epio.py
|
||||
|
||||
media/ = %(data_directory)s/
|
||||
|
||||
# #### If you're using Django, you'll want to uncomment some or all of these lines ####
|
||||
# [django]
|
||||
# # Path to your project root, relative to this directory.
|
||||
# base = .
|
||||
#
|
||||
# [static]
|
||||
# Serve the admin media
|
||||
# # Django 1.3
|
||||
# /static/admin = ../shortcuts/django-admin-media/
|
||||
# # Django 1.2 and below
|
||||
# /media = ../shortcuts/django-admin-media/
|
||||
#
|
||||
# [env]
|
||||
# # Use a different settings module for ep.io (i.e. with DEBUG=False)
|
||||
# DJANGO_SETTINGS_MODULE = production_settings
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
from django.core.management import execute_manager
|
||||
try:
|
||||
import settings # Assumed to be in the same directory.
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
execute_manager(settings)
|
|
@ -1 +0,0 @@
|
|||
Force media/objectstore directory to created
|
|
@ -1 +0,0 @@
|
|||
Force media/pygments directory to created
|
|
@ -1,25 +0,0 @@
|
|||
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.mixins import ResponseMixin
|
||||
from djangorestframework.renderers import DEFAULT_RENDERERS
|
||||
from djangorestframework.response import Response
|
||||
from djangorestframework.reverse import reverse
|
||||
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
|
||||
class ExampleView(ResponseMixin, View):
|
||||
"""An example view using Django 1.3's class based views.
|
||||
Uses djangorestframework's RendererMixin to provide support for multiple
|
||||
output formats."""
|
||||
renderers = DEFAULT_RENDERERS
|
||||
|
||||
def get(self, request):
|
||||
url = reverse('mixin-view', request=request)
|
||||
response = Response(200, {'description': 'Some example content',
|
||||
'url': url})
|
||||
return self.render(response)
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', ExampleView.as_view(), name='mixin-view'),
|
||||
)
|
|
@ -1,18 +0,0 @@
|
|||
from django.db import models
|
||||
|
||||
MAX_INSTANCES = 10
|
||||
|
||||
|
||||
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)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
For the purposes of the sandbox limit the maximum number of stored models.
|
||||
"""
|
||||
super(MyModel, self).save(*args, **kwargs)
|
||||
while MyModel.objects.all().count() > MAX_INSTANCES:
|
||||
MyModel.objects.all().order_by('-created')[0].delete()
|
|
@ -1,14 +0,0 @@
|
|||
from djangorestframework.resources import ModelResource
|
||||
from djangorestframework.reverse import reverse
|
||||
from modelresourceexample.models import MyModel
|
||||
|
||||
|
||||
class MyModelResource(ModelResource):
|
||||
model = MyModel
|
||||
fields = ('foo', 'bar', 'baz', 'url')
|
||||
ordering = ('created',)
|
||||
|
||||
def url(self, instance):
|
||||
return reverse('model-resource-instance',
|
||||
kwargs={'id': instance.id},
|
||||
request=self.request)
|
|
@ -1,11 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
|
||||
from modelresourceexample.resources import MyModelResource
|
||||
|
||||
my_model_list = ListOrCreateModelView.as_view(resource=MyModelResource)
|
||||
my_model_instance = InstanceModelView.as_view(resource=MyModelResource)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', my_model_list, name='model-resource-root'),
|
||||
url(r'^(?P<id>[0-9]+)/$', my_model_instance, name='model-resource-instance'),
|
||||
)
|
|
@ -1,7 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from objectstore.views import ObjectStoreRoot, StoredObject
|
||||
|
||||
urlpatterns = patterns('objectstore.views',
|
||||
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'),
|
||||
)
|
|
@ -1,109 +0,0 @@
|
|||
from django.conf import settings
|
||||
|
||||
from djangorestframework.reverse import reverse
|
||||
from djangorestframework.views import View
|
||||
from djangorestframework.response import Response
|
||||
from djangorestframework import status
|
||||
|
||||
import pickle
|
||||
import os
|
||||
import uuid
|
||||
import operator
|
||||
|
||||
OBJECT_STORE_DIR = os.path.join(settings.MEDIA_ROOT, 'objectstore')
|
||||
MAX_FILES = 10
|
||||
|
||||
if not os.path.exists(OBJECT_STORE_DIR):
|
||||
os.makedirs(OBJECT_STORE_DIR)
|
||||
|
||||
|
||||
def remove_oldest_files(dir, max_files):
|
||||
"""
|
||||
Remove the oldest files in a directory 'dir', leaving at most 'max_files' remaining.
|
||||
We use this to limit the number of resources in the sandbox.
|
||||
"""
|
||||
filepaths = [os.path.join(dir, file) for file in os.listdir(dir) if not file.startswith('.')]
|
||||
ctime_sorted_paths = [item[0] for item in sorted([(path, os.path.getctime(path)) for path in filepaths],
|
||||
key=operator.itemgetter(1), reverse=True)]
|
||||
[os.remove(path) for path in ctime_sorted_paths[max_files:]]
|
||||
|
||||
|
||||
def get_filename(key):
|
||||
"""
|
||||
Given a stored object's key returns the file's path.
|
||||
"""
|
||||
return os.path.join(OBJECT_STORE_DIR, key)
|
||||
|
||||
|
||||
def get_file_url(key, request):
|
||||
"""
|
||||
Given a stored object's key returns the URL for the object.
|
||||
"""
|
||||
return reverse('stored-object', kwargs={'key': key}, request=request)
|
||||
|
||||
|
||||
class ObjectStoreRoot(View):
|
||||
"""
|
||||
Root of the Object Store API.
|
||||
Allows the client to get a complete list of all the stored objects, or to create a new stored object.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Return a list of all the stored object URLs. (Ordered by creation time, newest first)
|
||||
"""
|
||||
filepaths = [os.path.join(OBJECT_STORE_DIR, file)
|
||||
for file in os.listdir(OBJECT_STORE_DIR)
|
||||
if not file.startswith('.')]
|
||||
ctime_sorted_basenames = [item[0] for item in sorted([(os.path.basename(path), os.path.getctime(path)) for path in filepaths],
|
||||
key=operator.itemgetter(1), reverse=True)]
|
||||
content = [get_file_url(key, request)
|
||||
for key in ctime_sorted_basenames]
|
||||
return Response(content)
|
||||
|
||||
def post(self, request):
|
||||
"""
|
||||
Create a new stored object, with a unique key.
|
||||
"""
|
||||
key = str(uuid.uuid1())
|
||||
filename = get_filename(key)
|
||||
pickle.dump(self.CONTENT, open(filename, 'wb'))
|
||||
|
||||
remove_oldest_files(OBJECT_STORE_DIR, MAX_FILES)
|
||||
url = get_file_url(key, request)
|
||||
return Response(self.CONTENT, status.HTTP_201_CREATED, {'Location': url})
|
||||
|
||||
|
||||
class StoredObject(View):
|
||||
"""
|
||||
Represents a stored object.
|
||||
The object may be any picklable content.
|
||||
"""
|
||||
def get(self, request, key):
|
||||
"""
|
||||
Return a stored object, by unpickling the contents of a locally
|
||||
stored file.
|
||||
"""
|
||||
filename = get_filename(key)
|
||||
if not os.path.exists(filename):
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
return Response(pickle.load(open(filename, 'rb')))
|
||||
|
||||
def put(self, request, key):
|
||||
"""
|
||||
Update/create a stored object, by pickling the request content to a
|
||||
locally stored file.
|
||||
"""
|
||||
filename = get_filename(key)
|
||||
pickle.dump(self.CONTENT, open(filename, 'wb'))
|
||||
return Response(self.CONTENT)
|
||||
|
||||
def delete(self, request, key):
|
||||
"""
|
||||
Delete a stored object, by removing it's pickled file.
|
||||
"""
|
||||
filename = get_filename(key)
|
||||
if not os.path.exists(filename):
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
os.remove(filename)
|
||||
return Response()
|
|
@ -1,18 +0,0 @@
|
|||
[
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "auth.user",
|
||||
"fields": {
|
||||
"username": "test",
|
||||
"first_name": "",
|
||||
"last_name": "",
|
||||
"is_active": true,
|
||||
"is_superuser": false,
|
||||
"is_staff": false,
|
||||
"groups": [],
|
||||
"user_permissions": [],
|
||||
"password": "sha1$b3dff$671b4ab97f2714446da32670d27576614e176758",
|
||||
"email": ""
|
||||
}
|
||||
}
|
||||
]
|
|
@ -1 +0,0 @@
|
|||
#for fixture loading
|
|
@ -1,27 +0,0 @@
|
|||
from django.test import TestCase
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.test.client import Client
|
||||
|
||||
|
||||
class NaviguatePermissionsExamples(TestCase):
|
||||
"""
|
||||
Sanity checks for permissions examples
|
||||
"""
|
||||
|
||||
def test_throttled_resource(self):
|
||||
url = reverse('throttled-resource')
|
||||
for i in range(0, 10):
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 503)
|
||||
|
||||
|
||||
def test_loggedin_resource(self):
|
||||
url = reverse('loggedin-resource')
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
loggedin_client = Client()
|
||||
loggedin_client.login(username='test', password='test')
|
||||
response = loggedin_client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
|
@ -1,8 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from permissionsexample.views import PermissionsExampleView, ThrottlingExampleView, LoggedInExampleView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', PermissionsExampleView.as_view(), name='permissions-example'),
|
||||
url(r'^throttling$', ThrottlingExampleView.as_view(), name='throttled-resource'),
|
||||
url(r'^loggedin$', LoggedInExampleView.as_view(), name='loggedin-resource'),
|
||||
)
|
|
@ -1,53 +0,0 @@
|
|||
from djangorestframework.views import View
|
||||
from djangorestframework.response import Response
|
||||
from djangorestframework.permissions import PerUserThrottling, IsAuthenticated
|
||||
from djangorestframework.reverse import reverse
|
||||
|
||||
|
||||
class PermissionsExampleView(View):
|
||||
"""
|
||||
A container view for permissions examples.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
return Response([
|
||||
{
|
||||
'name': 'Throttling Example',
|
||||
'url': reverse('throttled-resource', request)
|
||||
},
|
||||
{
|
||||
'name': 'Logged in example',
|
||||
'url': reverse('loggedin-resource', request)
|
||||
},
|
||||
])
|
||||
|
||||
|
||||
class ThrottlingExampleView(View):
|
||||
"""
|
||||
A basic read-only View that has a **per-user throttle** of 10 requests per minute.
|
||||
|
||||
If a user exceeds the 10 requests limit within a period of one minute, the
|
||||
throttle will be applied until 60 seconds have passed since the first request.
|
||||
"""
|
||||
|
||||
permissions_classes = (PerUserThrottling,)
|
||||
throttle = '10/min'
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Handle GET requests.
|
||||
"""
|
||||
return Response("Successful response to GET request because throttle is not yet active.")
|
||||
|
||||
|
||||
class LoggedInExampleView(View):
|
||||
"""
|
||||
You can login with **'test', 'test'.** or use curl:
|
||||
|
||||
`curl -X GET -H 'Accept: application/json' -u test:test http://localhost:8000/permissions-example`
|
||||
"""
|
||||
|
||||
permissions_classes = (IsAuthenticated, )
|
||||
|
||||
def get(self, request):
|
||||
return Response('You have permission to view this resource')
|
|
@ -1,27 +0,0 @@
|
|||
from django import forms
|
||||
|
||||
from pygments.lexers import get_all_lexers
|
||||
from pygments.styles import get_all_styles
|
||||
|
||||
LEXER_CHOICES = sorted([(item[1][0], item[0]) for item in get_all_lexers()])
|
||||
STYLE_CHOICES = sorted((item, item) for item in list(get_all_styles()))
|
||||
|
||||
|
||||
class PygmentsForm(forms.Form):
|
||||
"""A simple form with some of the most important pygments settings.
|
||||
The code to be highlighted can be specified either in a text field, or by URL.
|
||||
We do some additional form validation to ensure clients see helpful error responses."""
|
||||
|
||||
code = forms.CharField(widget=forms.Textarea,
|
||||
label='Code Text',
|
||||
max_length=1000000,
|
||||
help_text='(Copy and paste the code text here.)')
|
||||
title = forms.CharField(required=False,
|
||||
help_text='(Optional)',
|
||||
max_length=100)
|
||||
linenos = forms.BooleanField(label='Show Line Numbers',
|
||||
required=False)
|
||||
lexer = forms.ChoiceField(choices=LEXER_CHOICES,
|
||||
initial='python')
|
||||
style = forms.ChoiceField(choices=STYLE_CHOICES,
|
||||
initial='friendly')
|
|
@ -1 +0,0 @@
|
|||
#We need models.py otherwise the test framework complains (http://code.djangoproject.com/ticket/7198)
|
|
@ -1,46 +0,0 @@
|
|||
from django.test import TestCase
|
||||
from django.utils import simplejson as json
|
||||
|
||||
from djangorestframework.compat import RequestFactory
|
||||
|
||||
from pygments_api import views
|
||||
import tempfile, shutil
|
||||
|
||||
|
||||
|
||||
class TestPygmentsExample(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.factory = RequestFactory()
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
views.HIGHLIGHTED_CODE_DIR = self.temp_dir
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
shutil.rmtree(self.temp_dir)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def test_get_to_root(self):
|
||||
'''Just do a get on the base url'''
|
||||
request = self.factory.get('/pygments')
|
||||
view = views.PygmentsRoot.as_view()
|
||||
response = view(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_snippets_datetime_sorted(self):
|
||||
'''Pygments examples should be datetime sorted'''
|
||||
locations = []
|
||||
for snippet in 'abcdefghij': # String length must not exceed views.MAX_FILES, otherwise test fails
|
||||
form_data = {'code': '%s' % snippet, 'style':'friendly', 'lexer':'python'}
|
||||
request = self.factory.post('/pygments', data=form_data)
|
||||
view = views.PygmentsRoot.as_view()
|
||||
response = view(request)
|
||||
locations.append(response.items()[2][1])
|
||||
import time
|
||||
time.sleep(.1)
|
||||
request = self.factory.get('/pygments')
|
||||
view = views.PygmentsRoot.as_view()
|
||||
response = view(request)
|
||||
response_locations = json.loads(response.content)
|
||||
self.assertEquals(locations, response_locations)
|
|
@ -1,7 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from pygments_api.views import PygmentsRoot, PygmentsInstance
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', PygmentsRoot.as_view(), name='pygments-root'),
|
||||
url(r'^([a-zA-Z0-9-]+)/$', PygmentsInstance.as_view(), name='pygments-instance'),
|
||||
)
|
|
@ -1,118 +0,0 @@
|
|||
from __future__ import with_statement # for python 2.5
|
||||
from django.conf import settings
|
||||
|
||||
from djangorestframework.response import Response
|
||||
from djangorestframework.renderers import BaseRenderer
|
||||
from djangorestframework.reverse import reverse
|
||||
from djangorestframework.views import View
|
||||
from djangorestframework import status
|
||||
|
||||
from pygments.formatters import HtmlFormatter
|
||||
from pygments.lexers import get_lexer_by_name
|
||||
from pygments import highlight
|
||||
|
||||
from forms import PygmentsForm
|
||||
|
||||
import os
|
||||
import uuid
|
||||
import operator
|
||||
|
||||
# We need somewhere to store the code snippets that we highlight
|
||||
HIGHLIGHTED_CODE_DIR = os.path.join(settings.MEDIA_ROOT, 'pygments')
|
||||
MAX_FILES = 10
|
||||
|
||||
if not os.path.exists(HIGHLIGHTED_CODE_DIR):
|
||||
os.makedirs(HIGHLIGHTED_CODE_DIR)
|
||||
|
||||
|
||||
def list_dir_sorted_by_ctime(dir):
|
||||
"""
|
||||
Return a list of files sorted by creation time
|
||||
"""
|
||||
filepaths = [os.path.join(dir, file)
|
||||
for file in os.listdir(dir)
|
||||
if not file.startswith('.')]
|
||||
ctimes = [(path, os.path.getctime(path)) for path in filepaths]
|
||||
ctimes = sorted(ctimes, key=operator.itemgetter(1), reverse=False)
|
||||
return [filepath for filepath, ctime in ctimes]
|
||||
|
||||
|
||||
def remove_oldest_files(dir, max_files):
|
||||
"""
|
||||
Remove the oldest files in a directory 'dir', leaving at most 'max_files' remaining.
|
||||
We use this to limit the number of resources in the sandbox.
|
||||
"""
|
||||
[os.remove(path) for path in list_dir_sorted_by_ctime(dir)[max_files:]]
|
||||
|
||||
|
||||
class HTMLRenderer(BaseRenderer):
|
||||
"""
|
||||
Basic renderer which just returns the content without any further serialization.
|
||||
"""
|
||||
media_type = 'text/html'
|
||||
|
||||
|
||||
class PygmentsRoot(View):
|
||||
"""
|
||||
This example demonstrates a simple RESTful Web API around the awesome pygments library.
|
||||
This top level resource is used to create highlighted code snippets, and to list all the existing code snippets.
|
||||
"""
|
||||
form = PygmentsForm
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Return a list of all currently existing snippets.
|
||||
"""
|
||||
unique_ids = [os.path.split(f)[1]
|
||||
for f in list_dir_sorted_by_ctime(HIGHLIGHTED_CODE_DIR)]
|
||||
urls = [reverse('pygments-instance', args=[unique_id], request=request)
|
||||
for unique_id in unique_ids]
|
||||
return Response(urls)
|
||||
|
||||
def post(self, request):
|
||||
"""
|
||||
Create a new highlighed snippet and return it's location.
|
||||
For the purposes of the sandbox example, also ensure we delete the oldest snippets if we have > MAX_FILES.
|
||||
"""
|
||||
unique_id = str(uuid.uuid1())
|
||||
pathname = os.path.join(HIGHLIGHTED_CODE_DIR, unique_id)
|
||||
|
||||
lexer = get_lexer_by_name(self.CONTENT['lexer'])
|
||||
linenos = 'table' if self.CONTENT['linenos'] else False
|
||||
options = {'title': self.CONTENT['title']} if self.CONTENT['title'] else {}
|
||||
formatter = HtmlFormatter(style=self.CONTENT['style'], linenos=linenos, full=True, **options)
|
||||
|
||||
with open(pathname, 'w') as outfile:
|
||||
highlight(self.CONTENT['code'], lexer, formatter, outfile)
|
||||
|
||||
remove_oldest_files(HIGHLIGHTED_CODE_DIR, MAX_FILES)
|
||||
|
||||
location = reverse('pygments-instance', args=[unique_id], request=request)
|
||||
return Response(status=status.HTTP_201_CREATED, headers={'Location': location})
|
||||
|
||||
|
||||
class PygmentsInstance(View):
|
||||
"""
|
||||
Simply return the stored highlighted HTML file with the correct mime type.
|
||||
This Resource only renders HTML and uses a standard HTML renderer rather than the renderers.DocumentingHTMLRenderer class.
|
||||
"""
|
||||
renderers = (HTMLRenderer, )
|
||||
|
||||
def get(self, request, unique_id):
|
||||
"""
|
||||
Return the highlighted snippet.
|
||||
"""
|
||||
pathname = os.path.join(HIGHLIGHTED_CODE_DIR, unique_id)
|
||||
if not os.path.exists(pathname):
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
return Response(open(pathname, 'r').read())
|
||||
|
||||
def delete(self, request, unique_id):
|
||||
"""
|
||||
Delete the highlighted snippet.
|
||||
"""
|
||||
pathname = os.path.join(HIGHLIGHTED_CODE_DIR, unique_id)
|
||||
if not os.path.exists(pathname):
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
os.remove(pathname)
|
||||
return Response()
|
|
@ -1,3 +0,0 @@
|
|||
from django.db import models
|
||||
|
||||
# Create your models here.
|
|
@ -1,9 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from requestexample.views import RequestExampleView, EchoRequestContentView
|
||||
from examples.views import ProxyView
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', RequestExampleView.as_view(), name='request-example'),
|
||||
url(r'^content$', ProxyView.as_view(view_class=EchoRequestContentView), name='request-content'),
|
||||
)
|
|
@ -1,43 +0,0 @@
|
|||
from djangorestframework.compat import View
|
||||
from django.http import HttpResponse
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from djangorestframework.mixins import RequestMixin
|
||||
from djangorestframework.views import View as DRFView
|
||||
from djangorestframework import parsers
|
||||
from djangorestframework.response import Response
|
||||
|
||||
|
||||
class RequestExampleView(DRFView):
|
||||
"""
|
||||
A container view for request examples.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
return Response([{'name': 'request.DATA Example', 'url': reverse('request-content')},])
|
||||
|
||||
|
||||
class MyBaseViewUsingEnhancedRequest(RequestMixin, View):
|
||||
"""
|
||||
Base view enabling the usage of enhanced requests with user defined views.
|
||||
"""
|
||||
|
||||
parsers = parsers.DEFAULT_PARSERS
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.request = request = self.create_request(request)
|
||||
return super(MyBaseViewUsingEnhancedRequest, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
|
||||
class EchoRequestContentView(MyBaseViewUsingEnhancedRequest):
|
||||
"""
|
||||
A view that just reads the items in `request.DATA` and echoes them back.
|
||||
"""
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return HttpResponse(("Found %s in request.DATA, content : %s" %
|
||||
(type(request.DATA), request.DATA)))
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
return HttpResponse(("Found %s in request.DATA, content : %s" %
|
||||
(type(request.DATA), request.DATA)))
|
|
@ -1,3 +0,0 @@
|
|||
Pygments==1.4
|
||||
Markdown==2.0.3
|
||||
git+git://github.com/tomchristie/django-rest-framework.git
|
|
@ -1,7 +0,0 @@
|
|||
# Pygments for the code highlighting example,
|
||||
# markdown for the docstring -> auto-documentation
|
||||
|
||||
Pygments==1.4
|
||||
Markdown==2.0.3
|
||||
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
from django import forms
|
||||
|
||||
|
||||
class MyForm(forms.Form):
|
||||
foo = forms.BooleanField(required=False)
|
||||
bar = forms.IntegerField(help_text='Must be an integer.')
|
||||
baz = forms.CharField(max_length=32, help_text='Free text. Max length 32 chars.')
|
|
@ -1,7 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from resourceexample.views import ExampleView, AnotherExampleView
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', ExampleView.as_view(), name='example-resource'),
|
||||
url(r'^(?P<num>[0-9]+)/$', AnotherExampleView.as_view(), name='another-example'),
|
||||
)
|
|
@ -1,49 +0,0 @@
|
|||
from djangorestframework.reverse import reverse
|
||||
from djangorestframework.views import View
|
||||
from djangorestframework.response import Response
|
||||
from djangorestframework import status
|
||||
|
||||
from resourceexample.forms import MyForm
|
||||
|
||||
|
||||
class ExampleView(View):
|
||||
"""
|
||||
A basic read-only view that points to 3 other views.
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Handle GET requests, returning a list of URLs pointing to
|
||||
three other views.
|
||||
"""
|
||||
resource_urls = [reverse('another-example',
|
||||
kwargs={'num': num},
|
||||
request=request)
|
||||
for num in range(3)]
|
||||
return Response({"Some other resources": resource_urls})
|
||||
|
||||
|
||||
class AnotherExampleView(View):
|
||||
"""
|
||||
A basic view, that can handle GET and POST requests.
|
||||
Applies some simple form validation on POST requests.
|
||||
"""
|
||||
form = MyForm
|
||||
|
||||
def get(self, request, num):
|
||||
"""
|
||||
Handle GET requests.
|
||||
Returns a simple string indicating which view the GET request was for.
|
||||
"""
|
||||
if int(num) > 2:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
return Response("GET request to AnotherExampleResource %s" % num)
|
||||
|
||||
def post(self, request, num):
|
||||
"""
|
||||
Handle POST requests, with form validation.
|
||||
Returns a simple string indicating what content was supplied.
|
||||
"""
|
||||
if int(num) > 2:
|
||||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
return Response("POST request to AnotherExampleResource %s, with content: %s" % (num, repr(self.CONTENT)))
|
|
@ -1,44 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
|
||||
|
||||
from django.conf import settings
|
||||
from django.test.utils import get_runner
|
||||
from coverage import coverage
|
||||
|
||||
def main():
|
||||
"""Run the tests for the examples and generate a coverage report."""
|
||||
|
||||
# Discover the list of all modules that we should test coverage for
|
||||
project_dir = os.path.dirname(__file__)
|
||||
cov_files = []
|
||||
for (path, dirs, files) in os.walk(project_dir):
|
||||
# Drop tests and runtests directories from the test coverage report
|
||||
if os.path.basename(path) == 'tests' or os.path.basename(path) == 'runtests':
|
||||
continue
|
||||
cov_files.extend([os.path.join(path, file) for file in files if file.endswith('.py')])
|
||||
TestRunner = get_runner(settings)
|
||||
|
||||
cov = coverage()
|
||||
cov.erase()
|
||||
cov.start()
|
||||
if hasattr(TestRunner, 'func_name'):
|
||||
# Pre 1.2 test runners were just functions,
|
||||
# and did not support the 'failfast' option.
|
||||
import warnings
|
||||
warnings.warn(
|
||||
'Function-based test runners are deprecated. Test runners should be classes with a run_tests() method.',
|
||||
DeprecationWarning
|
||||
)
|
||||
failures = TestRunner(None)
|
||||
else:
|
||||
test_runner = TestRunner()
|
||||
failures = test_runner.run_tests(['blogpost', 'pygments_api'])
|
||||
|
||||
cov.stop()
|
||||
cov.report(cov_files)
|
||||
cov.xml_report(cov_files)
|
||||
sys.exit(failures)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,65 +0,0 @@
|
|||
"""The root view for the examples provided with Django REST framework"""
|
||||
|
||||
from djangorestframework.reverse import reverse
|
||||
from djangorestframework.views import View
|
||||
from djangorestframework.response import Response
|
||||
|
||||
|
||||
class Sandbox(View):
|
||||
"""
|
||||
This is the sandbox for the examples provided with
|
||||
[Django REST framework][1].
|
||||
|
||||
These examples are provided to help you get a better idea of 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.
|
||||
|
||||
For example, to get the default representation using curl:
|
||||
|
||||
bash: curl -X GET http://rest.ep.io/
|
||||
|
||||
Or, to get the plaintext documentation represention:
|
||||
|
||||
bash: curl -X GET http://rest.ep.io/ -H 'Accept: text/plain'
|
||||
|
||||
The examples provided:
|
||||
|
||||
1. A basic example using the [Resource][2] class.
|
||||
2. A basic example using the [ModelResource][3] class.
|
||||
3. An basic example using Django 1.3's [class based views][4] and
|
||||
djangorestframework's [RendererMixin][5].
|
||||
4. A generic object store API.
|
||||
5. A code highlighting API.
|
||||
6. A blog posts and comments API.
|
||||
7. A basic example using permissions.
|
||||
8. A basic example using enhanced request.
|
||||
|
||||
Please feel free to browse, create, edit and delete the resources in
|
||||
these examples.
|
||||
|
||||
[1]: http://django-rest-framework.org
|
||||
[2]: http://django-rest-framework.org/library/resource.html
|
||||
[3]: http://django-rest-framework.org/library/modelresource.html
|
||||
[4]: http://docs.djangoproject.com/en/dev/topics/class-based-views/
|
||||
[5]: http://django-rest-framework.org/library/renderers.html
|
||||
"""
|
||||
|
||||
def get(self, request):
|
||||
return Response([
|
||||
{'name': 'Simple Resource example',
|
||||
'url': reverse('example-resource', request=request)},
|
||||
{'name': 'Simple ModelResource example',
|
||||
'url': reverse('model-resource-root', request=request)},
|
||||
{'name': 'Simple Mixin-only example',
|
||||
'url': reverse('mixin-view', request=request)},
|
||||
{'name': 'Object store API',
|
||||
'url': reverse('object-store-root', request=request)},
|
||||
{'name': 'Code highlighting API',
|
||||
'url': reverse('pygments-root', request=request)},
|
||||
{'name': 'Blog posts API',
|
||||
'url': reverse('blog-posts-root', request=request)},
|
||||
{'name': 'Permissions example',
|
||||
'url': reverse('permissions-example', request=request)},
|
||||
])
|
|
@ -1,117 +0,0 @@
|
|||
# Settings for djangorestframework examples project
|
||||
import django
|
||||
import os
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@domain.com'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
'NAME': 'sqlite3.db', # Or path to database file if using sqlite3.
|
||||
'USER': '', # Not used with sqlite3.
|
||||
'PASSWORD': '', # Not used with sqlite3.
|
||||
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
|
||||
'PORT': '', # Set to empty string for default. Not used with sqlite3.
|
||||
}
|
||||
}
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# On Unix systems, a value of None will cause Django to use the same
|
||||
# timezone as the operating system.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'Europe/London'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-uk'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# If you set this to False, Django will not format dates, numbers and
|
||||
# calendars according to the current locale
|
||||
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 = os.path.join(os.getenv('EPIO_DATA_DIRECTORY', '.'), '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 = '/uploads/'
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = 't&9mru2_k$t8e2-9uq-wu2a1)9v*us&j3i#lsqkt(lbx*vh1cu'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
# 'django.template.loaders.eggs.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'urls'
|
||||
|
||||
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.
|
||||
)
|
||||
|
||||
if django.VERSION < (1, 3):
|
||||
staticfiles = 'staticfiles'
|
||||
else:
|
||||
staticfiles = 'django.contrib.staticfiles'
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
staticfiles,
|
||||
'django.contrib.messages',
|
||||
|
||||
'djangorestframework',
|
||||
|
||||
'resourceexample',
|
||||
'modelresourceexample',
|
||||
'objectstore',
|
||||
'pygments_api',
|
||||
'blogpost',
|
||||
'permissionsexample',
|
||||
'requestexample',
|
||||
)
|
||||
|
||||
import os
|
||||
if os.environ.get('HUDSON_URL', None):
|
||||
TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner'
|
||||
TEST_OUTPUT_VERBOSE = True
|
||||
TEST_OUTPUT_DESCRIPTIONS = True
|
||||
TEST_OUTPUT_DIR = 'xmlrunner'
|
|
@ -1,21 +0,0 @@
|
|||
from django.conf.urls.defaults import patterns, include, url
|
||||
from sandbox.views import Sandbox
|
||||
try:
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
except ImportError: # Django <= 1.2
|
||||
from staticfiles.urls import staticfiles_urlpatterns
|
||||
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', Sandbox.as_view()),
|
||||
(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'^permissions-example/', include('permissionsexample.urls')),
|
||||
url(r'^restframework/', include('djangorestframework.urls', namespace='djangorestframework')),
|
||||
)
|
||||
|
||||
urlpatterns += staticfiles_urlpatterns()
|
|
@ -1,32 +0,0 @@
|
|||
from djangorestframework.views import View
|
||||
from djangorestframework.response import Response
|
||||
|
||||
|
||||
class ProxyView(View):
|
||||
"""
|
||||
A view that just acts as a proxy to call non-djangorestframework views, while still
|
||||
displaying the browsable API interface.
|
||||
"""
|
||||
|
||||
view_class = None
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
self.request = request = self.create_request(request)
|
||||
if request.method in ['PUT', 'POST']:
|
||||
self.response = self.view_class.as_view()(request, *args, **kwargs)
|
||||
return super(ProxyView, self).dispatch(request, *args, **kwargs)
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return Response()
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
return Response(self.response.content)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
return Response(self.response.content)
|
||||
|
||||
def get_name(self):
|
||||
return self.view_class.__name__
|
||||
|
||||
def get_description(self, html):
|
||||
return self.view_class.__doc__
|
Loading…
Reference in New Issue
Block a user