aboutsummaryrefslogtreecommitdiffstats
path: root/src/rest
diff options
context:
space:
mode:
authorTom Christie2011-01-11 18:01:02 +0000
committerTom Christie2011-01-11 18:01:02 +0000
commit42825e44e14ca89ba97dd5c144f9f078fa762f1e (patch)
treec4633709ee1094d57d60528065bd8cdc3c839d51 /src/rest
parent95ac2396d65c42f7b801d8760dc00020d2f33e12 (diff)
downloaddjango-rest-framework-42825e44e14ca89ba97dd5c144f9f078fa762f1e.tar.bz2
Sample example working
Diffstat (limited to 'src/rest')
-rw-r--r--src/rest/emitters.py2
-rw-r--r--src/rest/resource.py124
-rw-r--r--src/rest/templates/emitter.html4
-rw-r--r--src/rest/templatetags/urlize_quoted_links.py6
-rw-r--r--src/rest/templatetags/urlize_quoted_links.pycbin4515 -> 4547 bytes
5 files changed, 101 insertions, 35 deletions
diff --git a/src/rest/emitters.py b/src/rest/emitters.py
index bafbf372..87faa559 100644
--- a/src/rest/emitters.py
+++ b/src/rest/emitters.py
@@ -18,7 +18,7 @@ class TemplatedEmitter(BaseEmitter):
template = None
def emit(self, output):
- content = json.dumps(output, indent=4)
+ content = json.dumps(output, indent=4, sort_keys=True)
template = loader.get_template(self.template)
context = RequestContext(self.request, {
'content': content,
diff --git a/src/rest/resource.py b/src/rest/resource.py
index f14b2ba5..c57ebfad 100644
--- a/src/rest/resource.py
+++ b/src/rest/resource.py
@@ -137,15 +137,20 @@ class Resource(object):
- def determine_form(self, data=None):
+ def determine_form(self, input_data=None, return_data=None):
"""Optionally return a Django Form instance, which may be used for validation
and/or rendered by an HTML/XHTML emitter.
- The data argument will be non Null if the form is required to be bound to some deserialized
- input data, or Null if the form is required to be unbound.
+ The input_data or return_data arguments can be used to bind the form either to the deserialized input,
+ or to a return object.
"""
if self.form:
- return self.form(data)
+ if input_data:
+ return self.form(input_data)
+ elif return_data:
+ return self.form(return_data)
+ else:
+ return self.form()
return None
@@ -259,12 +264,13 @@ class Resource(object):
if method in ('PUT', 'POST'):
parser = self.determine_parser(request)
data = parser(self, request).parse(request.raw_post_data)
- form = self.determine_form(data)
+ form = self.determine_form(input_data=data)
data = self.cleanup_request(data, form)
(status, ret, headers) = func(data, request.META, *args, **kwargs)
else:
(status, ret, headers) = func(request.META, *args, **kwargs)
+ form = self.determine_form(return_data=ret)
except ResourceException, exc:
@@ -274,7 +280,7 @@ class Resource(object):
if emitter is None:
mimetype, emitter = self.emitters[0]
- # Use a form unbound to any data if one has not yet been created
+ # Create an unbound form if one has not yet been created
if form is None:
form = self.determine_form()
@@ -284,7 +290,6 @@ class Resource(object):
# Serialize the response content
ret = self.cleanup_response(ret)
content = emitter(self, request, status, headers, form).emit(ret)
- print content
# Build the HTTP Response
resp = HttpResponse(content, mimetype=mimetype, status=status)
@@ -308,7 +313,7 @@ class ModelResource(Resource):
fields = None
form_fields = None
- def determine_form(self, data=None):
+ def determine_form(self, input_data=None, return_data=None):
"""Return a form that may be used in validation and/or rendering an html emitter"""
if self.form:
return self.form
@@ -317,12 +322,14 @@ class ModelResource(Resource):
class NewModelForm(ModelForm):
class Meta:
model = self.model
- fields = self.form_fields if self.form_fields else self.fields
+ fields = self.form_fields if self.form_fields else None #self.fields
- if data is None:
- return NewModelForm()
+ if input_data:
+ return NewModelForm(input_data)
+ elif return_data:
+ return NewModelForm(instance=return_data)
else:
- return NewModelForm(data)
+ return NewModelForm()
else:
return None
@@ -359,6 +366,12 @@ class ModelResource(Resource):
ret = _list(thing)
elif isinstance(thing, dict):
ret = _dict(thing)
+ elif isinstance(thing, int):
+ ret = thing
+ elif isinstance(thing, bool):
+ ret = thing
+ elif isinstance(thing, type(None)):
+ ret = thing
elif isinstance(thing, decimal.Decimal):
ret = str(thing)
elif isinstance(thing, Model):
@@ -417,7 +430,7 @@ class ModelResource(Resource):
ret = { }
#handler = self.in_typemapper(type(data), self.anonymous) # TRC
handler = None # TRC
- get_absolute_uri = False
+ get_absolute_url = False
if handler or fields:
v = lambda f: getattr(data, f.attname)
@@ -444,12 +457,13 @@ class ModelResource(Resource):
for field in get_fields.copy():
if exclude.match(field):
get_fields.discard(field)
-
+
+ get_absolute_url = True
+
else:
get_fields = set(fields)
-
- if 'absolute_uri' in get_fields: # MOVED (TRC)
- get_absolute_uri = True
+ if 'absolute_url' in get_fields: # MOVED (TRC)
+ get_absolute_url = True
met_fields = _method_fields(handler, get_fields) # TRC
@@ -508,14 +522,37 @@ class ModelResource(Resource):
# ret[maybe_field] = _any(handler_f(data))
else:
+ # Add absolute_url if it exists
+ get_absolute_url = True
+
+ # Add all the fields
for f in data._meta.fields:
- ret[f.attname] = _any(getattr(data, f.attname))
+ if f.attname != 'id':
+ ret[f.attname] = _any(getattr(data, f.attname))
- fields = dir(data.__class__) + ret.keys()
- add_ons = [k for k in dir(data) if k not in fields]
+ # Add all the propertiess
+ klass = data.__class__
+ for attr in dir(klass):
+ if not attr.startswith('_') and not attr in ('pk','id') and isinstance(getattr(klass, attr, None), property):
+ #if attr.endswith('_url') or attr.endswith('_uri'):
+ # ret[attr] = self.make_absolute(_any(getattr(data, attr)))
+ #else:
+ ret[attr] = _any(getattr(data, attr))
+ #fields = dir(data.__class__) + ret.keys()
+ #add_ons = [k for k in dir(data) if k not in fields and not k.startswith('_')]
+ #print add_ons
+ ###print dir(data.__class__)
+ #from django.db.models import Model
+ #model_fields = dir(Model)
+
+ #for attr in dir(data):
+ ## #if attr.startswith('_'):
+ ## # continue
+ # if (attr in fields) and not (attr in model_fields) and not attr.startswith('_'):
+ # print attr, type(getattr(data, attr, None)), attr in fields, attr in model_fields
- for k in add_ons:
- ret[k] = _any(getattr(data, k))
+ #for k in add_ons:
+ # ret[k] = _any(getattr(data, k))
# TRC
# resouce uri
@@ -532,9 +569,13 @@ class ModelResource(Resource):
# except: pass
# absolute uri
- if hasattr(data, 'get_absolute_url') and get_absolute_uri:
- try: ret['absolute_uri'] = self.make_absolute(data.get_absolute_url())
+ if hasattr(data, 'get_absolute_url') and get_absolute_url:
+ try: ret['absolute_url'] = self.make_absolute(data.get_absolute_url())
except: pass
+
+ for key, val in ret.items():
+ if key.endswith('_url') or key.endswith('_uri'):
+ ret[key] = self.make_absolute(val)
return ret
@@ -560,8 +601,9 @@ class ModelResource(Resource):
return _any(data, self.fields)
- def create(self, data, headers={}):
- instance = self.model(**data)
+ def create(self, data, headers={}, *args, **kwargs):
+ all_kw_args = dict(data.items() + kwargs.items())
+ instance = self.model(**all_kw_args)
instance.save()
headers = {}
if hasattr(instance, 'get_absolute_url'):
@@ -569,17 +611,37 @@ class ModelResource(Resource):
return (201, instance, headers)
def read(self, headers={}, *args, **kwargs):
- instance = self.model.objects.get(**kwargs)
+ try:
+ instance = self.model.objects.get(**kwargs)
+ except self.model.DoesNotExist:
+ return (404, '', {})
+
return (200, instance, {})
def update(self, data, headers={}, *args, **kwargs):
- instance = self.model.objects.get(**kwargs)
- for (key, val) in data.items():
- setattr(instance, key, val)
+ try:
+ instance = self.model.objects.get(**kwargs)
+ for (key, val) in data.items():
+ setattr(instance, key, val)
+ except self.model.DoesNotExist:
+ instance = self.model(**data)
+ instance.save()
+
instance.save()
return (200, instance, {})
def delete(self, headers={}, *args, **kwargs):
instance = self.model.objects.get(**kwargs)
instance.delete()
- return (204, '', {}) \ No newline at end of file
+ return (204, '', {})
+
+
+class QueryModelResource(ModelResource):
+ allowed_methods = ('read',)
+
+ def determine_form(self, input_data=None, return_data=None):
+ return None
+
+ def read(self, headers={}, *args, **kwargs):
+ query = self.model.objects.all()
+ return (200, query, {})
diff --git a/src/rest/templates/emitter.html b/src/rest/templates/emitter.html
index 8be41b7c..ddc91fbf 100644
--- a/src/rest/templates/emitter.html
+++ b/src/rest/templates/emitter.html
@@ -11,10 +11,10 @@
<body>
<h1>{{ resource_name }}</h1>
<p>{{ resource_doc }}</p>
- <pre>{% autoescape off %}<b>{{ status }} {{ reason }}</b>
+ <pre><b>{{ status }} {{ reason }}</b>{% autoescape off %}
{% for key, val in headers.items %}<b>{{ key }}:</b> {{ val|urlize_quoted_links }}
{% endfor %}
-{{ content|urlize_quoted_links }}{% endautoescape %} </pre>
+{{ content|urlize_quoted_links }} </pre>{% endautoescape %}
{% if 'read' in resource.allowed_operations %}
<div class='action'>
diff --git a/src/rest/templatetags/urlize_quoted_links.py b/src/rest/templatetags/urlize_quoted_links.py
index cef179bf..4e3ae6c8 100644
--- a/src/rest/templatetags/urlize_quoted_links.py
+++ b/src/rest/templatetags/urlize_quoted_links.py
@@ -33,7 +33,7 @@ html_gunk_re = re.compile(r'(?:<br clear="all">|<i><\/i>|<b><\/b>|<em><\/em>|<st
hard_coded_bullets_re = re.compile(r'((?:<p>(?:%s).*?[a-zA-Z].*?</p>\s*)+)' % '|'.join([re.escape(x) for x in DOTS]), re.DOTALL)
trailing_empty_content_re = re.compile(r'(?:<p>(?:&nbsp;|\s|<br \/>)*?</p>\s*)+\Z')
-def urlize_quoted_links(text, trim_url_limit=None, nofollow=False, autoescape=False):
+def urlize_quoted_links(text, trim_url_limit=None, nofollow=False, autoescape=True):
"""
Converts any URLs in text into clickable links.
@@ -90,6 +90,10 @@ def urlize_quoted_links(text, trim_url_limit=None, nofollow=False, autoescape=Fa
words[i] = escape(word)
return u''.join(words)
+
+#urlize_quoted_links.needs_autoescape = True
+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()
diff --git a/src/rest/templatetags/urlize_quoted_links.pyc b/src/rest/templatetags/urlize_quoted_links.pyc
index b49e16b6..cc77f97f 100644
--- a/src/rest/templatetags/urlize_quoted_links.pyc
+++ b/src/rest/templatetags/urlize_quoted_links.pyc
Binary files differ