aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Christie2011-01-28 17:42:57 +0000
committerTom Christie2011-01-28 17:42:57 +0000
commit40f47a9fb31aebd965dce03ae57c036d5360d124 (patch)
tree9e95ee3e500b5c2d8eb4e1adecefaf1d2de47b8a
parent2e9fd9c6b93a77dcf5caa42a4d71b9da2021693f (diff)
downloaddjango-rest-framework-40f47a9fb31aebd965dce03ae57c036d5360d124.tar.bz2
Minor bit of tidy up (all the stuff I noticed when demoing to francis)
-rw-r--r--docs/emitters.rst2
-rw-r--r--docs/index.rst24
-rw-r--r--examples/pygments_api/forms.py52
-rw-r--r--examples/pygments_api/views.py2
-rw-r--r--examples/urls.py1
-rw-r--r--flywheel/emitters.py7
-rw-r--r--flywheel/resource.py13
-rw-r--r--flywheel/templates/emitter.html8
8 files changed, 47 insertions, 62 deletions
diff --git a/docs/emitters.rst b/docs/emitters.rst
index fcea6151..590ace0f 100644
--- a/docs/emitters.rst
+++ b/docs/emitters.rst
@@ -1,8 +1,6 @@
:mod:`emitters`
===============
-.. module:: emitters
-
The emitters module provides a set of emitters that can be plugged in to a :class:`.Resource`. An emitter is responsible for taking the output of a and serializing it to a given media type. A :class:`.Resource` can have a number of emitters, allow the same content to be serialized in a number of different formats depending on the requesting client's preferences, as specified in the HTTP Request's Accept header.
.. automodule:: emitters
diff --git a/docs/index.rst b/docs/index.rst
index a6bdaab8..10e41f7a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -13,8 +13,30 @@ Some of FlyWheel's features:
* Optional support for forms as input validation.
* Modular architecture - Easy to extend and modify.
+Installation & Setup
+--------------------
+
+blah di blah
+
+Getting Started
+---------------
+
+Blah di blah
+
+
+Examples
+--------
+
+Blah blah blah, examples here.
+
+Add a toctree for examples
+
+
+Library Reference
+-----------------
+
.. toctree::
- :maxdepth: 1
+ :maxdepth: 2
resource
modelresource
diff --git a/examples/pygments_api/forms.py b/examples/pygments_api/forms.py
index 66446c5b..dc9927e2 100644
--- a/examples/pygments_api/forms.py
+++ b/examples/pygments_api/forms.py
@@ -15,57 +15,11 @@ class PygmentsForm(forms.Form):
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_url = forms.URLField(required=False, label='Code URL',
- help_text='eg. https://bitbucket.org/tomchristie/flywheel/raw/cc266285d879/flywheel/resource.py')
- code_text = forms.CharField(widget=forms.Textarea, required=False, label='Code Text',
- help_text='Either supply a URL for the code to be highlighted or copy and paste the code text here.')
- title = forms.CharField(required=False, help_text='(Optional)')
+ 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')
-
- def clean_code_url(self):
- """Custom field validation.
- Ensure that code URLs really are valid, and return the content they point to in the cleaned_data,
- rather than returning the URL itself."""
- cleaned_data = self.cleaned_data
- url = cleaned_data.get('code_url')
- if not url:
- return ''
-
- try:
- http = httplib.Http('.cache')
- resp, content = http.request(url)
- except:
- raise forms.ValidationError('The URL supplied cannot be reached')
-
- if int(resp.status/100) != 2:
- raise forms.ValidationError('The URL supplied does not return successfully')
- if not content:
- raise forms.ValidationError('The URL supplied returns no content')
-
- return content
-
-
- def clean(self):
- """Custom form validation.
- Ensure that only one of code_url and code_text is set, and return the content of whichever is set in 'code'."""
- cleaned_data = self.cleaned_data
- code_url = cleaned_data.get('code_url')
- code_text = cleaned_data.get('code_text')
-
- if not code_url and not code_text:
- raise forms.ValidationError('Either the URL or the code text must be supplied')
- if code_url and code_text:
- raise forms.ValidationError('You may not specify both the URL and the code text')
-
- if code_url:
- cleaned_data['code'] = code_url
- del cleaned_data['code_url']
- else:
- cleaned_data['code'] = code_text
- del cleaned_data['code_text']
-
- return cleaned_data
diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py
index 02f541f3..4493a822 100644
--- a/examples/pygments_api/views.py
+++ b/examples/pygments_api/views.py
@@ -24,7 +24,7 @@ class HTMLEmitter(BaseEmitter):
class PygmentsRoot(Resource):
"""This example demonstrates a simple RESTful Web API aound the awesome pygments library.
- This top level resource is used to create """
+ This top level resource is used to create highlighted code snippets."""
form = PygmentsForm
allowed_methods = anon_allowed_methods = ('POST',)
diff --git a/examples/urls.py b/examples/urls.py
index b1dec13d..48af39de 100644
--- a/examples/urls.py
+++ b/examples/urls.py
@@ -7,6 +7,7 @@ urlpatterns = patterns('',
(r'^pygments-example/', include('pygments_api.urls')),
(r'^blog-post-example/', include('blogpost.urls')),
(r'^object-store-example/', include('objectstore.urls')),
+ (r'^testarchive-example/', include('testarchive.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')),
diff --git a/flywheel/emitters.py b/flywheel/emitters.py
index d052d965..57e95ec2 100644
--- a/flywheel/emitters.py
+++ b/flywheel/emitters.py
@@ -32,6 +32,8 @@ class BaseEmitter(object):
self.resource = resource
def emit(self, output=NoContent, verbose=False):
+ """By default emit simply returns the ouput as-is.
+ Override this method to provide for other behaviour."""
if output is NoContent:
return ''
@@ -81,7 +83,8 @@ class DocumentingTemplateEmitter(BaseEmitter):
provide a form that can be used to submit arbitrary content."""
# Get the form instance if we have one bound to the input
form_instance = resource.form_instance
-
+ print form_instance
+
# Otherwise if this isn't an error response
# then attempt to get a form bound to the response object
if not form_instance and resource.response.has_content_body:
@@ -89,6 +92,8 @@ class DocumentingTemplateEmitter(BaseEmitter):
form_instance = resource.get_form(resource.response.raw_content)
except:
pass
+ if form_instance and not form_instance.is_valid():
+ form_instance = None
# If we still don't have a form instance then try to get an unbound form
if not form_instance:
diff --git a/flywheel/resource.py b/flywheel/resource.py
index 677bdfce..2a8554f3 100644
--- a/flywheel/resource.py
+++ b/flywheel/resource.py
@@ -58,14 +58,19 @@ class Resource(object):
CSRF_PARAM = 'csrfmiddlewaretoken' # Django's CSRF token used in form params
- def __new__(cls, request, *args, **kwargs):
+ def __new__(cls, *args, **kwargs):
"""Make the class callable so it can be used as a Django view."""
self = object.__new__(cls)
- self.__init__(request)
- return self._handle_request(request, *args, **kwargs)
+ if args:
+ request = args[0]
+ self.__init__(request)
+ return self._handle_request(request, *args[1:], **kwargs)
+ else:
+ self.__init__()
+ return self
- def __init__(self, request):
+ def __init__(self, request=None):
""""""
# Setup the resource context
self.request = request
diff --git a/flywheel/templates/emitter.html b/flywheel/templates/emitter.html
index 7959af17..4b0a7ce9 100644
--- a/flywheel/templates/emitter.html
+++ b/flywheel/templates/emitter.html
@@ -30,9 +30,9 @@
<h1>{{ resource.name }}</h1>
<p>{{ resource.description|linebreaksbr }}</p>
<pre><b>{{ response.status }} {{ response.status_text }}</b>{% autoescape off %}
- {% for key, val in response.headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }}
- {% endfor %}
- {{ content|urlize_quoted_links }}</pre>{% endautoescape %}
+{% for key, val in response.headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }}
+{% endfor %}
+{{ content|urlize_quoted_links }}</pre>{% endautoescape %}
{% if 'GET' in resource.allowed_methods %}
<div class='action'>
@@ -40,7 +40,7 @@
<ul class="accepttypes">
{% for media_type in resource.emitted_media_types %}
{% with resource.ACCEPT_QUERY_PARAM|add:"="|add:media_type as param %}
- <li>[<a href='{{ request.path|add_query_param:param }} rel="nofollow"'>{{ media_type }}</a>]</li>
+ <li>[<a href='{{ request.path|add_query_param:param }}' rel="nofollow">{{ media_type }}</a>]</li>
{% endwith %}
{% endfor %}
</ul>